ViennaNET: safn af bakenda bókasöfnum. 2. hluti

Raiffeisenbank .NET þróunarsamfélagið heldur áfram að fara stuttlega yfir innihald ViennaNET. Um hvernig og hvers vegna við komumst að þessu, þú getur lesið fyrsta hlutann.

Í þessari grein munum við fara í gegnum bókasöfn sem enn hafa ekki verið íhuguð til að vinna með dreifðar færslur, biðraðir og gagnagrunna, sem er að finna í GitHub geymslunni okkar (heimildir eru hér), og Nuget pakkar hér.

ViennaNET: safn af bakenda bókasöfnum. 2. hluti

ViennaNET.Sagas

Þegar verkefni skiptir yfir í DDD og örþjónustuarkitektúr, þá þegar viðskiptarökfræði er dreift yfir mismunandi þjónustu, kemur upp vandamál sem tengist þörfinni á að innleiða dreifða viðskiptakerfi, vegna þess að margar aðstæður hafa oft áhrif á mörg lén í einu. Þú getur kynnst slíkum aðferðum nánar, til dæmis, í bókinni "Microservices Patterns", Chris Richardson.

Í verkefnum okkar höfum við innleitt einfalt en gagnlegt fyrirkomulag: Saga, eða öllu heldur hljómsveitarsaga. Kjarni þess er sem hér segir: það er ákveðin viðskiptaatburðarás þar sem nauðsynlegt er að framkvæma aðgerðir í röð í mismunandi þjónustu, og ef einhver vandamál koma upp í einhverju skrefi, er nauðsynlegt að kalla afturköllunarferlið fyrir öll fyrri skref, þar sem það er veitt. Þannig, í lok sögunnar, óháð árangri, fáum við samræmd gögn á öllum sviðum.

Innleiðingin okkar er enn gerð í grunnformi og er ekki bundin við notkun á neinum aðferðum við samskipti við aðra þjónustu. Það er ekki erfitt í notkun: búðu bara til afkomanda af grunn óhlutbundnum flokki SagaBase, þar sem T er samhengisflokkurinn þinn þar sem þú getur geymt fyrstu gögnin sem nauðsynleg eru til að sagan virki, auk nokkurra milliniðurstaðna. Samhengistilvikið verður flutt í öll skref meðan á framkvæmd stendur. Saga sjálf er ríkisfangslaus klassi, þannig að hægt er að setja tilvikið í DI sem Singleton til að fá nauðsynlegar ósjálfstæði.

Dæmi fyrir auglýsingu:

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

Dæmi um símtal:

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

Hægt er að skoða heildardæmi um mismunandi útfærslur hér og í samsetningu með prófum.

ViennaNET.Orm.*

Safn af bókasöfnum til að vinna með ýmsa gagnagrunna í gegnum Nhibernate. Við notum DB-First nálgunina með Liquibase, þannig að það er aðeins virkni til að vinna með gögn í tilbúnum gagnagrunni.

ViennaNET.Orm.Seedwork и ViennaNET.Orm – aðalsamsetningar sem innihalda grunnviðmót og útfærslur þeirra, í sömu röð. Við skulum skoða innihald þeirra nánar.

tengi IEntityFactoryService og framkvæmd þess EntityFactoryService eru aðal upphafspunkturinn til að vinna með gagnagrunninn, þar sem vinnueiningin, geymslur til að vinna með tilteknum aðilum, sem og framkvæmdarstjórar skipana og beinar SQL fyrirspurnir eru búnar til hér. Stundum er þægilegt að takmarka getu bekkjar til að vinna með gagnagrunn, til dæmis til að geta aðeins lesið gögn. Fyrir slík tilvik IEntityFactoryService það er forfaðir - tengi IEntityRepositoryFactory, sem aðeins lýsir yfir aðferð til að búa til geymslur.

Til að fá beinan aðgang að gagnagrunninum er veitandakerfið notað. Hver DBMS sem við notum í teymunum okkar hefur sína eigin útfærslu: ViennaNET.Orm.MSSQL, ViennaNET.Orm.Oracle, ViennaNET.Orm.SQLite, ViennaNET.Orm.PostgreSql.

Jafnframt er hægt að skrá nokkra þjónustuveitendur í einni umsókn samtímis, sem gerir til dæmis kleift, innan ramma einnar þjónustu, án kostnaðar við breytingar á innviðum, að framkvæma skref-fyrir-skref flutning frá eitt DBMS í annað. Aðgerðin til að velja nauðsynlega tengingu og þar af leiðandi veituna fyrir tiltekinn einingaflokk (sem kortlagning á gagnagrunnstöflur er skrifuð fyrir) er útfærð með því að skrá eininguna í BoundedContext flokkinn (inniheldur aðferð til að skrá lénseiningar) eða arftaka hans ApplicationContext (inniheldur aðferðir til að skrá forritaeiningar, beinar beiðnir og skipanir), þar sem tengingaauðkenni frá uppsetningu er samþykkt sem rök:

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

Dæmi um umsóknarsamhengi:

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

Ef auðkenni tengingarinnar er ekki tilgreint, þá verður tengingin sem heitir „default“ notuð.

Bein kortlagning aðila á gagnagrunnstöflur er útfærð með því að nota staðlaða NHibernate verkfæri. Þú getur notað lýsinguna bæði í gegnum xml skrár og í gegnum flokka. Til að auðvelda ritun á stubbageymslum í einingaprófum er til bókasafn ViennaNET.TestUtils.Orm.

Full dæmi um notkun ViennaNET.Orm.* má finna hér.

ViennaNET.Messaging.*

Sett af bókasöfnum til að vinna með biðraðir.

Til að vinna með biðraðir var sama nálgun valin og með ýmsar DBMS, nefnilega hámarks mögulega sameinaða nálgun hvað varðar vinnu við bókasafnið, óháð því hvaða biðröð er notaður. Bókasafn ViennaNET.Messaging ber einmitt ábyrgð á þessari sameiningu, og ViennaNET.Messaging.MQSeriesQueue, ViennaNET.Messaging.RabbitMQQueue и ViennaNET.Messaging.KafkaQueue innihalda millistykki útfærslur fyrir IBM MQ, RabbitMQ og Kafka, í sömu röð.

Þegar unnið er með biðraðir eru tveir ferlar: móttaka skilaboða og senda þau.

Íhuga að taka á móti. Það eru 2 valkostir hér: fyrir stöðuga hlustun og til að taka á móti einum skilaboðum. Til að hlusta stöðugt á biðröðina verður þú fyrst að lýsa örgjörvaflokknum sem erfður frá IMessageProcessor, sem mun sjá um að afgreiða skilaboðin sem berast. Næst verður það að vera „tengt“ við ákveðna biðröð; þetta er gert með skráningu inn IQueueReactorFactory sem gefur til kynna biðraðarauðkenni úr uppsetningunni:

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

Dæmi um að byrja að hlusta:

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

Síðan, þegar þjónustan byrjar og aðferðin er kölluð til að byrja að hlusta, fara öll skilaboð úr tilgreindri biðröð til samsvarandi örgjörva.

Til að fá ein skilaboð í verksmiðjuviðmóti IMessagingComponentFactory það er til aðferð CreateMessageReceiversem mun búa til viðtakanda sem bíður eftir skilaboðum úr biðröðinni sem tilgreind er fyrir hann:

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

Til að senda skilaboð þú þarft að nota það sama IMessagingComponentFactory og búðu til skilaboðasendanda:

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

Það eru þrír tilbúnir valkostir til að raða og afsala skilaboðum: bara texta, XML og JSON, en ef nauðsyn krefur geturðu auðveldlega búið til þínar eigin viðmótsútfærslur IMessageSerializer и IMessageDeserializer.

Við höfum reynt að varðveita einstaka möguleika hvers biðraðarstjóra, t.d. ViennaNET.Messaging.MQSeriesQueue gerir þér kleift að senda ekki aðeins texta, heldur einnig bætiskilaboð, og ViennaNET.Messaging.RabbitMQQueue styður leiðsögn og biðraðir á flugi. Millistykkið okkar fyrir RabbitMQ útfærir líka einhvern svip á RPC: við sendum skilaboð og bíðum eftir svari frá sérstakri tímabundinni biðröð, sem er aðeins búin til fyrir eitt svarskilaboð.

Hér dæmi um að nota biðraðir með helstu blæbrigðum tenginga.

ViennaNET.CallContext

Við notum biðraðir ekki aðeins til samþættingar á milli mismunandi kerfa, heldur einnig til samskipta milli örþjónustu sama forrits, til dæmis innan sögu. Þetta leiddi til þess að þurfa að senda ásamt skilaboðunum aukagögn eins og notendainnskráningu, beiðniauðkenni fyrir end-til-enda skráningu, uppruna IP-tölu og heimildargögn. Til að útfæra framsendingu þessara gagna þróuðum við bókasafn ViennaNET.CallContext, sem gerir þér kleift að geyma gögn frá beiðni sem fer inn í þjónustuna. Í þessu tilviki skiptir ekki máli hvernig beiðnin var gerð, í gegnum biðröð eða í gegnum Http. Síðan, áður en sendan beiðni eða skilaboð eru send, eru gögn tekin úr samhenginu og sett í hausana. Þannig tekur næsta þjónusta við aukagögnunum og heldur utan um þau á sama hátt.

Þakka þér fyrir athygli þína, við hlökkum til athugasemda þinna og draga beiðnir!

Heimild: www.habr.com

Bæta við athugasemd