ViennaNET: sett ta' libreriji għall-backend. Parti 2

Il-komunità tal-iżviluppaturi Raiffeisenbank .NET tkompli tirrevedi fil-qosor il-kontenut ta' ViennaNET. Dwar kif u għaliex wasalna għal dan, tista' taqra l-ewwel parti.

F'dan l-artikolu, se ngħaddu minn libreriji li għad iridu jiġu kkunsidrati biex naħdmu ma' tranżazzjonijiet, kjuwijiet u databases distribwiti, li jistgħu jinstabu fir-repożitorju GitHub tagħna (sorsi huma hawn), u Pakketti Nuget hawn.

ViennaNET: sett ta' libreriji għall-backend. Parti 2

ViennaNET.Sagas

Meta proġett jaqleb għal DDD u arkitettura ta 'mikroservizz, allura meta l-loġika tan-negozju titqassam f'servizzi differenti, tqum problema relatata mal-ħtieġa li jiġi implimentat mekkaniżmu ta' tranżazzjoni distribwita, minħabba li ħafna xenarji ħafna drabi jaffettwaw diversi oqsma f'daqqa. Tista' ssir familjari ma' mekkaniżmi bħal dawn f'aktar dettall, pereżempju, fil-ktieb "Microservices Patterns", Chris Richardson.

Fil-proġetti tagħna, implimentajna mekkaniżmu sempliċi iżda utli: saga, jew aħjar saga bbażata fuq l-orkestrazzjoni. L-essenza tagħha hija kif ġej: hemm ċertu xenarju tan-negozju li fih huwa meħtieġ li jitwettqu b'mod sekwenzjali operazzjonijiet f'servizzi differenti, u jekk jinqalgħu xi problemi fi kwalunkwe pass, huwa meħtieġ li tissejjaħ il-proċedura ta 'rollback għall-passi preċedenti kollha, fejn ikun ipprovdut. Għalhekk, fl-aħħar tas-saga, irrispettivament mis-suċċess, nirċievu dejta konsistenti fl-oqsma kollha.

L-implimentazzjoni tagħna għadha ssir fil-forma bażika tagħha u mhijiex marbuta mal-użu ta’ xi metodi ta’ interazzjoni ma’ servizzi oħra. Mhuwiex diffiċli biex tużah: agħmel dixxendent tal-klassi astratta bażi SagaBase<T>, fejn T hija l-klassi tal-kuntest tiegħek li fiha tista 'taħżen id-dejta inizjali meħtieġa biex is-saga taħdem, kif ukoll xi riżultati intermedji. L-istanza tal-kuntest se tiġi mgħoddija lill-passi kollha matul l-eżekuzzjoni. Saga nnifisha hija klassi mingħajr stat, għalhekk l-istanza tista 'titqiegħed f'DI bħala Singleton biex tikseb id-dipendenzi meħtieġa.

Eżempju ta' reklam:

public class ExampleSaga : SagaBase<ExampleContext>
{
  public ExampleSaga()
  {
    Step("Step 1")
      .WithAction(c => ...)
      .WithCompensation(c => ...);
	
    AsyncStep("Step 2")
      .WithAction(async c => ...);
  }
}

Eżempju ta' sejħa:

var saga = new ExampleSaga();
var context = new ExampleContext();
await saga.Execute(context);

Eżempji sħaħ ta' implimentazzjonijiet differenti jistgħu jitqiesu hawn u fl-assemblaġġ ma testijiet.

ViennaNET.Orm.*

Sett ta’ libreriji biex taħdem ma’ diversi databases permezz ta’ Nhibernate. Aħna nużaw l-approċċ DB-First billi nużaw Liquibase, għalhekk hemm biss funzjonalità biex naħdmu mad-dejta f'database lesta.

ViennaNET.Orm.Seedwork и ViennaNET.Orm – assemblaġġi ewlenin li fihom interfaces bażiċi u l-implimentazzjonijiet tagħhom, rispettivament. Ejja nħarsu lejn il-kontenut tagħhom f'aktar dettall.

Interface IEntityFactoryService u l-implimentazzjoni tagħha EntityFactoryService huma l-punt tat-tluq ewlieni għall-ħidma mad-database, peress li l-Unità tax-Xogħol, repożitorji għal ħidma ma 'entitajiet speċifiċi, kif ukoll eżekuturi ta' kmandi u mistoqsijiet diretti SQL huma maħluqa hawn. Xi drabi huwa konvenjenti li tillimita l-kapaċitajiet ta 'klassi biex taħdem ma' database, pereżempju, biex tipprovdi l-abbiltà li taqra d-dejta biss. Għal każijiet bħal dawn IEntityFactoryService hemm antenat - interface IEntityRepositoryFactory, li jiddikjara biss metodu għall-ħolqien ta' repożitorji.

Biex taċċessa direttament id-database, jintuża l-mekkaniżmu tal-fornitur. Kull DBMS li nużaw fit-timijiet tagħna għandu l-implimentazzjoni tiegħu stess: ViennaNET.Orm.MSSQL, ViennaNET.Orm.Oracle, ViennaNET.Orm.SQLite, ViennaNET.Orm.PostgreSql.

Fl-istess ħin, diversi fornituri jistgħu jiġu rreġistrati f'applikazzjoni waħda fl-istess ħin, li tippermetti, pereżempju, fi ħdan il-qafas ta' servizz wieħed, mingħajr ebda spiża għall-modifika tal-infrastruttura, li jwettqu migrazzjoni pass pass minn DBMS wieħed għal ieħor. Il-mekkaniżmu għall-għażla tal-konnessjoni meħtieġa u, għalhekk, il-fornitur għal klassi ta’ entità speċifika (li għaliha huwa miktub l-immappjar tat-tabelli tad-database) huwa implimentat permezz tar-reġistrazzjoni tal-entità fil-klassi BoundedContext (fih metodu għar-reġistrazzjoni ta’ entitajiet ta’ dominju) jew is-suċċessur tagħha ApplicationContext (fih metodi għar-reġistrazzjoni ta' entitajiet tal-applikazzjoni , talbiet diretti u kmandi), fejn l-identifikatur tal-konnessjoni mill-konfigurazzjoni huwa aċċettat bħala argument:

"db": [
  {
    "nick": "mssql_connection",
    "dbServerType": "MSSQL",
    "ConnectionString": "...",
    "useCallContext": true
  },
  {
    "nick": "oracle_connection",
    "dbServerType": "Oracle",
    "ConnectionString": "..."
  }
],

Eżempju Applikazzjoni Kuntest:

internal sealed class DbContext : ApplicationContext
{
  public DbContext()
  {
    AddEntity<SomeEntity>("mssql_connection");
    AddEntity<MigratedSomeEntity>("oracle_connection");
    AddEntity<AnotherEntity>("oracle_connection");
  }
}

Jekk l-ID tal-konnessjoni ma jkunx speċifikat, allura l-konnessjoni msejħa "default" se tintuża.

L-immappjar dirett ta' entitajiet għal tabelli ta' database huwa implimentat bl-użu ta' għodod standard ta' NHibernate. Tista 'tuża d-deskrizzjoni kemm permezz ta' fajls xml kif ukoll permezz ta 'klassijiet. Għal kitba konvenjenti ta 'repożitorji stub fit-testijiet tal-Unità, hemm librerija ViennaNET.TestUtils.Orm.

Eżempji sħaħ tal-użu ta' ViennaNET.Orm.* jistgħu jinstabu hawn.

ViennaNET.Messaging.*

Sett ta’ libreriji biex taħdem bil-kjuwijiet.

Biex taħdem bil-kjuwijiet, intgħażel l-istess approċċ bħal ma 'diversi DBMSs, jiġifieri, l-approċċ unifikat massimu possibbli f'termini ta' ħidma mal-librerija, irrispettivament mill-maniġer tal-kju użat. Librerija ViennaNET.Messaging huwa preċiżament responsabbli għal din l-unifikazzjoni, u ViennaNET.Messaging.MQSeriesQueue, ViennaNET.Messaging.RabbitMQQueue и ViennaNET.Messaging.KafkaQueue fihom implimentazzjonijiet ta' adapter għal IBM MQ, RabbitMQ u Kafka, rispettivament.

Meta taħdem bil-kjuwijiet, hemm żewġ proċessi: li tirċievi messaġġ u tibgħatu.

Ikkunsidra li tirċievi. Hemm 2 għażliet hawnhekk: għal smigħ kontinwu u biex tirċievi messaġġ wieħed. Biex tisma 'l-kju kontinwament, l-ewwel trid tiddeskrivi l-klassi tal-proċessur li wiret minnha IMessageProcessor, li se tkun responsabbli għall-ipproċessar tal-messaġġ li jkun dieħel. Sussegwentement, għandu jkun "konness" ma 'kju speċifiku dan isir permezz ta' reġistrazzjoni; IQueueReactorFactory li jindika l-identifikatur tal-kju mill-konfigurazzjoni:

"messaging": {
    "ApplicationName": "MyApplication"
},
"rabbitmq": {
    "queues": [
      {
        "id": "myQueue",
        "queuename": "lalala",
        ...
      }
    ]
},

Eżempju ta’ kif tibda tisma’:

_queueReactorFactory.Register<MyMessageProcessor>("myQueue");
var queueReactor = queueReactorFactory.CreateQueueReactor("myQueue");
queueReactor.StartProcessing();

Imbagħad, meta s-servizz jibda u l-metodu jissejjaħ biex jibda jisma, il-messaġġi kollha mill-kju speċifikat se jmorru għall-proċessur korrispondenti.

Biex tirċievi messaġġ wieħed f'interface tal-fabbrika IMessagingComponentFactory hemm metodu CreateMessageReceiverli se joħloq riċevitur jistenna messaġġ mill-kju speċifikat lilu:

using (var receiver = _messagingComponentFactory.CreateMessageReceiver<TestMessage>("myQueue"))
{
    var message = receiver.Receive();
}

Biex tibgħat messaġġ għandek bżonn tuża l-istess IMessagingComponentFactory u oħloq min jibgħat il-messaġġ:

using (var sender = _messagingComponentFactory.CreateMessageSender<MyMessage>("myQueue"))
{
    sender.SendMessage(new MyMessage { Value = ...});
}

Hemm tliet għażliet lesti għas-serializing u deserializing messaġġ: test biss, XML u JSON, iżda jekk meħtieġ, tista 'faċilment tagħmel l-implimentazzjonijiet tal-interface tiegħek stess. IMessageSerializer и IMessageDeserializer.

Aħna ppruvajna nippreservaw il-kapaċitajiet uniċi ta’ kull maniġer tal-kju, eż. ViennaNET.Messaging.MQSeriesQueue jippermettilek li tibgħat mhux biss test, iżda wkoll messaġġi byte, u ViennaNET.Messaging.RabbitMQQueue jappoġġja r-rotot u l-kju on-the-fly. It-tgeżwir tal-adapter tagħna għal RabbitMQ jimplimenta wkoll xi semblanza ta 'RPC: nibagħtu messaġġ u nistennew rispons minn kju temporanju speċjali, li jinħoloq biss għal messaġġ ta' rispons wieħed.

Hawnhekk eżempju ta’ użu ta’ kjuwijiet bi sfumaturi bażiċi ta’ konnessjoni.

ViennaNET.CallContext

Aħna nużaw kjuwijiet mhux biss għall-integrazzjoni bejn sistemi differenti, iżda wkoll għall-komunikazzjoni bejn mikroservizzi tal-istess applikazzjoni, pereżempju, fi ħdan saga. Dan wassal għall-ħtieġa li flimkien mal-messaġġ tiġi trażmessa tali data awżiljarja bħall-login tal-utent, l-identifikatur tat-talba għal illoggjar minn tarf sa tarf, l-indirizz IP tas-sors u d-dejta tal-awtorizzazzjoni. Biex nimplimentaw it-trażmissjoni ta’ din id-dejta, żviluppajna librerija ViennaNET.CallContext, li jippermettilek taħżen data minn talba li tidħol fis-servizz. F'dan il-każ, il-mod kif saret it-talba, permezz ta' kju jew permezz ta' Http, ma jimpurtax. Imbagħad, qabel ma tintbagħat it-talba jew il-messaġġ li joħroġ, id-dejta tittieħed mill-kuntest u titqiegħed fl-intestaturi. Għalhekk, is-servizz li jmiss jirċievi d-dejta awżiljarja u jimmaniġġjaha bl-istess mod.

Grazzi għall-attenzjoni tiegħek, nistennew bil-ħerqa l-kummenti tiegħek u t-talbiet tiegħek!

Sors: www.habr.com

Żid kumment