Kominote pwomotè Raiffeisenbank .NET kontinye revize sa ki nan ViennaNET yon ti tan. Konsènan ki jan ak poukisa nou rive nan sa a, .
Nan atik sa a, nou pral ale nan bibliyotèk ki poko konsidere pou travay ak tranzaksyon distribye, ke moun kap kriye ak baz done, ki ka jwenn nan depo GitHub nou an (), yon .
ViennaNET.Sagas
Lè yon pwojè chanje nan DDD ak achitekti mikwosèvis, Lè sa a, lè lojik biznis yo distribye atravè sèvis diferan, yon pwoblèm rive ki gen rapò ak bezwen an aplike yon mekanis tranzaksyon distribye, paske anpil senaryo souvan afekte plizyè domèn nan yon fwa. Ou ka fè konesans ak mekanis sa yo an plis detay, pou egzanp, .
Nan pwojè nou yo, nou te aplike yon mekanis senp men itil: yon lejand, oswa pito yon lejand ki baze sou òkestrasyon. Sans li se jan sa a: gen yon senaryo biznis sèten nan ki li nesesè sekans fè operasyon nan diferan sèvis, epi si nenpòt pwoblèm rive nan nenpòt etap, li nesesè yo rele pwosedi a rollback pou tout etap anvan yo, kote li ye. bay. Kidonk, nan fen lejand la, kèlkeswa siksè, nou resevwa done ki konsistan nan tout domèn.
Aplikasyon nou an toujou fèt nan fòm debaz li yo epi li pa mare ak itilizasyon nenpòt metòd entèraksyon ak lòt sèvis. Li pa difisil pou itilize: jis fè yon desandan klas abstrè baz SagaBase<T>, kote T se klas kontèks ou kote ou ka estoke done inisyal ki nesesè pou lejand la travay, ansanm ak kèk rezilta entèmedyè. Enstans kontèks la pral pase nan tout etap pandan ekzekisyon an. Saga tèt li se yon klas apatrid, kidonk egzanp lan ka mete nan DI kòm yon Singleton pou jwenn depandans ki nesesè yo.
Egzanp anons:
public class ExampleSaga : SagaBase<ExampleContext>
{
public ExampleSaga()
{
Step("Step 1")
.WithAction(c => ...)
.WithCompensation(c => ...);
AsyncStep("Step 2")
.WithAction(async c => ...);
}
}
Egzanp apèl:
var saga = new ExampleSaga();
var context = new ExampleContext();
await saga.Execute(context);
Egzanp konplè sou aplikasyon diferan ka wè ak nan asanble ak .
ViennaNET.Orm.*
Yon seri bibliyotèk pou travay ak divès baz done atravè Nhibernate. Nou itilize apwòch DB-First lè l sèvi avèk Liquibase, kidonk gen sèlman fonksyonalite pou travay ak done nan yon baz done pare.
ViennaNET.Orm.Seedwork и ViennaNET.Orm – asanble prensipal ki gen entèfas debaz ak aplikasyon yo, respektivman. Ann gade sa yo nan plis detay.
koòdone IEntityFactoryService ak aplikasyon li EntityFactoryService se prensipal pwen depa pou travay ak baz done a, depi Inite travay la, depo pou travay ak antite espesifik, osi byen ke egzekitè kòmandman ak demann SQL dirèk yo kreye isit la. Pafwa li bon pou limite kapasite yon klas pou travay ak yon baz done, pou egzanp, bay kapasite pou li done sèlman. Pou ka sa yo IEntityFactoryService gen yon zansèt - koòdone IEntityRepositoryFactory, ki sèlman deklare yon metòd pou kreye depo.
Pou jwenn aksè dirèkteman nan baz done a, yo itilize mekanis founisè a. Chak DBMS nou itilize nan ekip nou yo gen pwòp aplikasyon li: ViennaNET.Orm.MSSQL, ViennaNET.Orm.Oracle, ViennaNET.Orm.SQLite, ViennaNET.Orm.PostgreSql.
An menm tan, plizyè founisè ka anrejistre nan yon aplikasyon an menm tan, ki pèmèt, pou egzanp, nan kad yon sèvis, san okenn depans pou modifye enfrastrikti a, fè yon migrasyon etap pa etap soti nan. yon DBMS nan yon lòt. Mekanis pou chwazi koneksyon ki nesesè yo ak, kidonk, founisè a pou yon klas antite espesifik (pou ki kat jeyografik tab baz done yo ekri) aplike nan enskri antite a nan klas BoundedContext (genyen yon metòd pou anrejistre antite domèn) oswa siksesè li yo. ApplicationContext (gen metòd pou anrejistre antite aplikasyon, demann dirèk ak kòmandman), kote idantifyan koneksyon ki soti nan konfigirasyon an aksepte kòm yon agiman:
"db": [
{
"nick": "mssql_connection",
"dbServerType": "MSSQL",
"ConnectionString": "...",
"useCallContext": true
},
{
"nick": "oracle_connection",
"dbServerType": "Oracle",
"ConnectionString": "..."
}
],
Egzanp ApplicationContext:
internal sealed class DbContext : ApplicationContext
{
public DbContext()
{
AddEntity<SomeEntity>("mssql_connection");
AddEntity<MigratedSomeEntity>("oracle_connection");
AddEntity<AnotherEntity>("oracle_connection");
}
}
Si idantifikasyon koneksyon an pa espesifye, Lè sa a, koneksyon ki rele "default" yo pral itilize.
Map dirèk antite nan tab baz done yo aplike lè l sèvi avèk zouti estanda NHibernate. Ou ka itilize deskripsyon an tou de atravè dosye xml ak nan klas yo. Pou redaksyon pratik nan depo souch nan tès inite yo, gen yon bibliyotèk ViennaNET.TestUtils.Orm.
Ou ka jwenn tout egzanp sou itilizasyon ViennaNET.Orm.* .
ViennaNET.Messaging.*
Yon seri bibliyotèk pou travay ak moun kap kriye.
Pou travay ak moun kap kriye, yo te chwazi menm apwòch la ak divès kalite DBMS, sètadi, maksimòm apwòch inifye posib an tèm de travay ak bibliyotèk la, kèlkeswa manadjè keu yo itilize. Bibliyotèk ViennaNET.Messaging se jisteman responsab pou inifikasyon sa a, epi ViennaNET.Messaging.MQSeriesQueue, ViennaNET.Messaging.RabbitMQQueue и ViennaNET.Messaging.KafkaQueue genyen aplikasyon adaptè pou IBM MQ, RabbitMQ ak Kafka, respektivman.
Lè w ap travay ak moun kap kriye, gen de pwosesis: resevwa yon mesaj ak voye li.
Konsidere resevwa. Gen 2 opsyon isit la: pou koute kontinyèl ak pou resevwa yon sèl mesaj. Pou toujou koute keu a, ou dwe premye dekri klas processeur eritye de IMessageProcessor, ki pral responsab pou trete mesaj kap vini an. Apre sa, li dwe "lye" nan yon keu espesifik sa a se fè nan enskripsyon an IQueueReactorFactory ki endike idantifyan keu a soti nan konfigirasyon an:
"messaging": {
"ApplicationName": "MyApplication"
},
"rabbitmq": {
"queues": [
{
"id": "myQueue",
"queuename": "lalala",
...
}
]
},
Egzanp pou kòmanse koute:
_queueReactorFactory.Register<MyMessageProcessor>("myQueue");
var queueReactor = queueReactorFactory.CreateQueueReactor("myQueue");
queueReactor.StartProcessing();
Lè sa a, lè sèvis la kòmanse epi yo rele metòd la kòmanse koute, tout mesaj ki soti nan keu espesifye yo pral ale nan processeur ki koresponn lan.
Pou resevwa yon mesaj sèl nan yon koòdone faktori IMessagingComponentFactory gen yon metòd CreateMessageReceiverki pral kreye yon moun k ap resevwa yon mesaj ki soti nan keu ki espesifye li:
using (var receiver = _messagingComponentFactory.CreateMessageReceiver<TestMessage>("myQueue"))
{
var message = receiver.Receive();
}
Pou voye yon mesaj ou bezwen sèvi ak menm bagay la IMessagingComponentFactory epi kreye yon moun k ap voye mesaj:
using (var sender = _messagingComponentFactory.CreateMessageSender<MyMessage>("myQueue"))
{
sender.SendMessage(new MyMessage { Value = ...});
}
Gen twa opsyon ki pare pou seri ak deserialize yon mesaj: jis tèks, XML ak JSON, men si sa nesesè, ou ka fasilman fè pwòp aplikasyon koòdone ou. IMessageSerializer и IMessageDeserializer.
Nou te eseye prezève kapasite inik chak manadjè keu, pa egzanp. ViennaNET.Messaging.MQSeriesQueue pèmèt ou voye pa sèlman tèks, men tou mesaj byte, ak ViennaNET.Messaging.RabbitMQQueue sipòte routage ak on-the-fly queuing. Anbalaj adaptè nou an pou RabbitMQ tou aplike kèk sanblab RPC: nou voye yon mesaj epi tann pou yon repons soti nan yon keu espesyal tanporè, ki se kreye sèlman pou yon mesaj repons.
Isit la .
ViennaNET.CallContext
Nou itilize keu pa sèlman pou entegrasyon ant diferan sistèm, men tou pou kominikasyon ant mikwosèvis nan menm aplikasyon an, pou egzanp, nan yon lejand. Sa a te mennen nan nesesite pou transmèt ansanm ak mesaj la done oksilyè tankou koneksyon itilizatè a, idantifyan demann pou antre bout-a-fen, adrès IP sous ak done otorizasyon. Pou aplike transmisyon done sa yo, nou devlope yon bibliyotèk ViennaNET.CallContext, ki pèmèt ou estoke done ki sòti nan yon demann k ap antre nan sèvis la. Nan ka sa a, ki jan yo te fè demann lan, atravè yon keu oswa atravè HTTP, pa gen pwoblèm. Lè sa a, anvan yo voye demann sortan an oswa mesaj, done yo pran nan kontèks la epi yo mete yo nan tèt yo. Kidonk, pwochen sèvis la resevwa done oksilyè yo epi jere li menm jan an.
Mèsi pou atansyon ou, nou tann kòmantè ou yo ak demann rale!
Sous: www.habr.com
