Raiffeisenbank .NET izstrÄdÄtÄju kopiena turpina Ä«si pÄrskatÄ«t ViennaNET saturu. Par to, kÄ un kÄpÄc mÄs nonÄcÄm pie tÄ,
Å ajÄ rakstÄ mÄs apskatÄ«sim vÄl neapsvÄrtÄs bibliotÄkas darbam ar izplatÄ«tajiem darÄ«jumiem, rindÄm un datu bÄzÄm, kuras var atrast mÅ«su GitHub repozitorijÄ (
ViennaNET.SÄgas
Projektam pÄrejot uz DDD un mikropakalpojumu arhitektÅ«ru, tad, kad biznesa loÄ£ika tiek sadalÄ«ta pa dažÄdiem servisiem, rodas problÄma saistÄ«bÄ ar nepiecieÅ”amÄ«bu ieviest izkliedÄtu transakciju mehÄnismu, jo daudzi scenÄriji nereti skar vairÄkus domÄnus vienlaikus. Ar Å”Ädiem mehÄnismiem var iepazÄ«ties sÄ«kÄk, piemÄram,
Savos projektos esam ieviesuÅ”i vienkÄrÅ”u, bet noderÄ«gu mehÄnismu: sÄgu, pareizÄk sakot, uz orÄ·estrÄciju balstÄ«tu sÄgu. TÄs bÅ«tÄ«ba ir Å”Äda: ir noteikts biznesa scenÄrijs, kurÄ ir nepiecieÅ”ams secÄ«gi veikt darbÄ«bas dažÄdos servisos, un, ja kÄdÄ solÄ« rodas problÄmas, ir nepiecieÅ”ams izsaukt atcelÅ”anas procedÅ«ru visiem iepriekÅ”Äjiem soļiem, kur tas ir nodroÅ”inÄta. TÄdÄjÄdi sÄgas beigÄs neatkarÄ«gi no panÄkumiem mÄs saÅemam konsekventus datus visÄs jomÄs.
MÅ«su ievieÅ”ana joprojÄm tiek veikta tÄ pamata formÄ un nav saistÄ«ta ar mijiedarbÄ«bas ar citiem pakalpojumiem metožu izmantoÅ”anu. To nav grÅ«ti izmantot: vienkÄrÅ”i izveidojiet pÄcteci no pamata abstraktÄs klases SagaBase<T>, kur T ir jÅ«su konteksta klase, kurÄ varat saglabÄt sÄkotnÄjos datus, kas nepiecieÅ”ami sÄgas darbÄ«bai, kÄ arÄ« dažus starprezultÄtus. Konteksta gadÄ«jums izpildes laikÄ tiks nodots visÄm darbÄ«bÄm. Pati Saga ir bezvalstnieku klase, tÄpÄc instanci var ievietot DI kÄ Singleton, lai iegÅ«tu nepiecieÅ”amÄs atkarÄ«bas.
ReklÄmas piemÄrs:
public class ExampleSaga : SagaBase<ExampleContext>
{
public ExampleSaga()
{
Step("Step 1")
.WithAction(c => ...)
.WithCompensation(c => ...);
AsyncStep("Step 2")
.WithAction(async c => ...);
}
}
Zvana piemÄrs:
var saga = new ExampleSaga();
var context = new ExampleContext();
await saga.Execute(context);
Pilnus dažÄdu implementÄciju piemÄrus var apskatÄ«t
ViennaNET.Orm.*
BibliotÄku komplekts darbam ar dažÄdÄm datu bÄzÄm, izmantojot Nhibernate. MÄs izmantojam DB-First pieeju, izmantojot Liquibase, tÄpÄc ir tikai funkcionalitÄte darbam ar datiem gatavÄ datu bÄzÄ.
ViennaNET.Orm.Seedwork Šø ViennaNET.Orm
ā galvenie komplekti, kas satur attiecÄ«gi pamata saskarnes un to realizÄcijas. ApskatÄ«sim to saturu sÄ«kÄk.
interfeiss IEntityFactoryService
un tÄs Ä«stenoÅ”ana EntityFactoryService
ir galvenais sÄkumpunkts darbam ar datu bÄzi, jo Å”eit tiek izveidoti darba vienÄ«ba, repozitoriji darbam ar konkrÄtÄm entÄ«tijÄm, kÄ arÄ« komandu izpildÄ«tÄji un tieÅ”ie SQL vaicÄjumi. DažkÄrt ir Ärti ierobežot klases iespÄjas darbam ar datu bÄzi, piemÄram, lai nodroÅ”inÄtu iespÄju tikai nolasÄ«t datus. TÄdiem gadÄ«jumiem IEntityFactoryService
ir sencis - interfeiss IEntityRepositoryFactory
, kas tikai deklarÄ repozitoriju izveides metodi.
Lai tieÅ”i piekļūtu datu bÄzei, tiek izmantots pakalpojumu sniedzÄja mehÄnisms. Katrai DBVS, ko izmantojam savÄs komandÄs, ir sava ievieÅ”ana: ViennaNET.Orm.MSSQL, ViennaNET.Orm.Oracle, ViennaNET.Orm.SQLite, ViennaNET.Orm.PostgreSql
.
Vienlaikus vienÄ aplikÄcijÄ var reÄ£istrÄt vairÄkus pakalpojumu sniedzÄjus vienlaikus, kas ļauj, piemÄram, viena pakalpojuma ietvaros bez jebkÄdÄm izmaksÄm par infrastruktÅ«ras pÄrveidoÅ”anu veikt soli pa solim migrÄciju no no vienas DBVS uz citu. MehÄnisms vajadzÄ«gÄ savienojuma un lÄ«dz ar to arÄ« nodroÅ”inÄtÄja izvÄlei konkrÄtai entÄ«tiju klasei (kurai ir rakstÄ«ta kartÄÅ”ana uz datu bÄzes tabulÄm) tiek Ä«stenots, reÄ£istrÄjot entÄ«tiju BoundedContext klasÄ (ietver domÄna entÄ«tiju reÄ£istrÄÅ”anas metodi) vai tÄs pÄcteci. ApplicationContext (satur metodes lietojumprogrammu entÄ«tiju reÄ£istrÄÅ”anai, tieÅ”os pieprasÄ«jumus un komandas), kur kÄ arguments tiek pieÅemts savienojuma identifikators no konfigurÄcijas:
"db": [
{
"nick": "mssql_connection",
"dbServerType": "MSSQL",
"ConnectionString": "...",
"useCallContext": true
},
{
"nick": "oracle_connection",
"dbServerType": "Oracle",
"ConnectionString": "..."
}
],
Lietojumprogrammas konteksta piemÄrs:
internal sealed class DbContext : ApplicationContext
{
public DbContext()
{
AddEntity<SomeEntity>("mssql_connection");
AddEntity<MigratedSomeEntity>("oracle_connection");
AddEntity<AnotherEntity>("oracle_connection");
}
}
Ja savienojuma ID nav norÄdÄ«ts, tiks izmantots savienojums ar nosaukumu ānoklusÄjumsā.
TieÅ”a entÄ«tiju kartÄÅ”ana datu bÄzes tabulÄm tiek Ä«stenota, izmantojot standarta NHibernate rÄ«kus. Aprakstu var izmantot gan caur xml failiem, gan caur klasÄm. Ärtai stub repozitoriju rakstÄ«Å”anai vienÄ«bas testos ir bibliotÄka ViennaNET.TestUtils.Orm
.
Pilnus ViennaNET.Orm.* izmantoÅ”anas piemÄrus var atrast
ViennaNET.ZiÅapmaiÅa.*
BibliotÄku komplekts darbam ar rindÄm.
Lai strÄdÄtu ar rindÄm, tika izvÄlÄta tÄda pati pieeja kÄ dažÄdÄm DBVS, proti, maksimÄli iespÄjamÄ vienotÄ pieeja darbam ar bibliotÄku neatkarÄ«gi no izmantotÄ rindu pÄrvaldnieka. BibliotÄka ViennaNET.Messaging
ir tieÅ”i atbildÄ«gs par Å”o apvienoÅ”anos, un ViennaNET.Messaging.MQSeriesQueue, ViennaNET.Messaging.RabbitMQQueue Šø ViennaNET.Messaging.KafkaQueue
satur adaptera implementÄcijas attiecÄ«gi IBM MQ, RabbitMQ un Kafka.
StrÄdÄjot ar rindÄm, ir divi procesi: ziÅojuma saÅemÅ”ana un nosÅ«tÄ«Å”ana.
Apsveriet iespÄju saÅemt. Å eit ir 2 iespÄjas: nepÄrtrauktai klausÄ«Å”anai un vienas ziÅas saÅemÅ”anai. Lai pastÄvÄ«gi klausÄ«tos rindu, vispirms jÄapraksta procesora klase, kas mantota no IMessageProcessor
, kas bÅ«s atbildÄ«gs par ienÄkoÅ”Ä ziÅojuma apstrÄdi. PÄc tam tai jÄbÅ«t āsaistÄ«taiā ar noteiktu rindu; tas tiek darÄ«ts, reÄ£istrÄjoties IQueueReactorFactory
norÄdot rindas identifikatoru no konfigurÄcijas:
"messaging": {
"ApplicationName": "MyApplication"
},
"rabbitmq": {
"queues": [
{
"id": "myQueue",
"queuename": "lalala",
...
}
]
},
KlausÄ«Å”anÄs sÄkÅ”anas piemÄrs:
_queueReactorFactory.Register<MyMessageProcessor>("myQueue");
var queueReactor = queueReactorFactory.CreateQueueReactor("myQueue");
queueReactor.StartProcessing();
PÄc tam, kad pakalpojums tiek startÄts un tiek izsaukta metode, lai sÄktu klausÄ«Å”anos, visi ziÅojumi no norÄdÄ«tÄs rindas nonÄks attiecÄ«gajÄ procesorÄ.
Lai saÅemtu vienu ziÅojumu rÅ«pnÄ«cas saskarnÄ IMessagingComponentFactory
ir metode CreateMessageReceiver
kas izveidos adresÄtu, kas gaida ziÅojumu no tam norÄdÄ«tÄs rindas:
using (var receiver = _messagingComponentFactory.CreateMessageReceiver<TestMessage>("myQueue"))
{
var message = receiver.Receive();
}
Lai nosÅ«tÄ«tu ziÅu jums ir jÄizmanto tas pats IMessagingComponentFactory
un izveidojiet ziÅojuma sÅ«tÄ«tÄju:
using (var sender = _messagingComponentFactory.CreateMessageSender<MyMessage>("myQueue"))
{
sender.SendMessage(new MyMessage { Value = ...});
}
ZiÅojuma serializÄÅ”anai un deserializÄÅ”anai ir trÄ«s gatavas opcijas: tikai teksts, XML un JSON, bet, ja nepiecieÅ”ams, varat viegli izveidot interfeisa implementÄcijas. IMessageSerializer Šø IMessageDeserializer
.
Esam centuÅ”ies saglabÄt katra rindas pÄrvaldnieka unikÄlÄs iespÄjas, piem. ViennaNET.Messaging.MQSeriesQueue
ļauj nosÅ«tÄ«t ne tikai teksta, bet arÄ« baitu ziÅas, un ViennaNET.Messaging.RabbitMQQueue
atbalsta marÅ”rutÄÅ”anu un rindu veidoÅ”anu lidojumÄ. MÅ«su RabbitMQ adaptera iesaiÅojums arÄ« ievieÅ” zinÄmu RPC lÄ«dzÄ«bu: mÄs nosÅ«tÄm ziÅojumu un gaidÄm atbildi no Ä«paÅ”as pagaidu rindas, kas tiek izveidota tikai vienam atbildes ziÅojumam.
Ŕeit ir
ViennaNET.CallContext
MÄs izmantojam rindas ne tikai integrÄcijai starp dažÄdÄm sistÄmÄm, bet arÄ« saziÅai starp vienas un tÄs paÅ”as aplikÄcijas mikropakalpojumiem, piemÄram, sÄgas ietvaros. Tas radÄ«ja nepiecieÅ”amÄ«bu kopÄ ar ziÅojumu pÄrsÅ«tÄ«t tÄdus papildu datus kÄ lietotÄja pieteikÅ”anÄs, pieprasÄ«juma identifikators pilnÄ«gai reÄ£istrÄÅ”anai, avota IP adrese un autorizÄcijas dati. Lai Ä«stenotu Å”o datu pÄrsÅ«tÄ«Å”anu, mÄs izstrÄdÄjÄm bibliotÄku ViennaNET.CallContext
, kas ļauj saglabÄt datus no pakalpojuma ievadÄ«Å”anas pieprasÄ«juma. Å ajÄ gadÄ«jumÄ pieprasÄ«juma iesniegÅ”anas veidam, izmantojot rindu vai HTTP, nav nozÄ«mes. Tad pirms izejoÅ”Ä pieprasÄ«juma vai ziÅojuma nosÅ«tÄ«Å”anas dati tiek Åemti no konteksta un ievietoti galvenÄs. TÄdÄjÄdi nÄkamais pakalpojums saÅem palÄ«gdatus un pÄrvalda tos tÄdÄ paÅ”Ä veidÄ.
Paldies par uzmanÄ«bu, gaidÄ«sim jÅ«su komentÄrus un pieprasÄ«jumus!
Avots: www.habr.com