ViennaNET: Π½Π°Π±ΠΎΡ€ ΠΎΡ‚ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ Π·Π° backend. Част 2

ΠžΠ±Ρ‰Π½ΠΎΡΡ‚Ρ‚Π° Π½Π° .NET Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΡ†ΠΈΡ‚Π΅ Π½Π° Π Π°ΠΉΡ„Π°ΠΉΠ·Π΅Π½Π±Π°Π½ΠΊ ΠΏΡ€ΠΎΠ΄ΡŠΠ»ΠΆΠ°Π²Π° с ΠΊΡ€Π°Ρ‚ΡŠΠΊ ΠΎΠ±Π·ΠΎΡ€ Π½Π° ΡΡŠΠ΄ΡŠΡ€ΠΆΠ°Π½ΠΈΠ΅Ρ‚ΠΎ Π½Π° ViennaNET. Π—Π° Ρ‚ΠΎΠ²Π° ΠΊΠ°ΠΊ ΠΈ Π·Π°Ρ‰ΠΎ стигнахмС Π΄ΠΎ Ρ‚ΡƒΠΊ, ΠΌΠΎΠΆΠ΅ Π΄Π° сС ΠΏΡ€ΠΎΡ‡Π΅Ρ‚Π΅ Π² ΠΏΡŠΡ€Π²Π°Ρ‚Π° част..

Π’ Ρ‚Π°Π·ΠΈ статия Ρ‰Π΅ Ρ€Π°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ ΠΎΡ‰Π΅ Π½Π΅Ρ€Π°Π·Π³Π»Π΅Π΄Π°Π½ΠΈΡ‚Π΅ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ Π·Π° Ρ€Π°Π±ΠΎΡ‚Π° с Ρ€Π°Π·ΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ, опашки ΠΈ Π±Π°Π·ΠΈ Π΄Π°Π½Π½ΠΈ, ΠΊΠΎΠΈΡ‚ΠΎ ΠΌΠΎΠΆΠ΅ Π΄Π° Π½Π°ΠΌΠ΅Ρ€ΠΈΡ‚Π΅ Π² Π½Π°ΡˆΠ΅Ρ‚ΠΎ Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅ Π² GitHub (ΠΈΠ·Ρ‚ΠΎΡ‡Π½ΠΈΡ†ΠΈΡ‚Π΅ са Ρ‚ΡƒΠΊ.), Π° Nuget ΠΏΠ°ΠΊΠ΅Ρ‚ΠΈΡ‚Π΅ са Ρ‚ΡƒΠΊ..

ViennaNET: Π½Π°Π±ΠΎΡ€ ΠΎΡ‚ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ Π·Π° backend. Част 2

ViennaNET.Sagas

ΠšΠΎΠ³Π°Ρ‚ΠΎ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ΡŠΡ‚ ΠΏΡ€Π΅ΠΌΠΈΠ½Π΅ Π½Π° DDD ΠΈ микросСрвисна Π°Ρ€Ρ…ΠΈΡ‚Π΅ΠΊΡ‚ΡƒΡ€Π°, разпрСдСлянСто Π½Π° бизнСс Π»ΠΎΠ³ΠΈΠΊΠ°Ρ‚Π° Π² Ρ€Π°Π·Π»ΠΈΡ‡Π½ΠΈ услуги създава ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ, ΡΠ²ΡŠΡ€Π·Π°Π½ с нСобходимостта ΠΎΡ‚ Ρ€Π΅Π°Π»ΠΈΠ·ΠΈΡ€Π°Π½Π΅Ρ‚ΠΎ Π½Π° ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΡŠΠΌ Π·Π° Ρ€Π°Π·ΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈ Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ, Ρ‚ΡŠΠΉ ΠΊΠ°Ρ‚ΠΎ ΠΌΠ½ΠΎΠ³ΠΎ сцСнарии чСсто засягат няколко Π΄ΠΎΠΌΠ΅ΠΉΠ½Π°. Π‘ ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΈ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΠΈ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΏΠΎ-ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎ Π΄Π° сС Π·Π°ΠΏΠΎΠ·Π½Π°Π΅Ρ‚Π΅, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π² ΠΊΠ½ΠΈΠ³Π°Ρ‚Π° β€žMicroservices Patterns”, Chris Richardson..

Π’ Π½Π°ΡˆΠΈΡ‚Π΅ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ΠΈ Ρ€Π΅Π°Π»ΠΈΠ·ΠΈΡ€Π°Ρ…ΠΌΠ΅ прост, Π½ΠΎ ΠΏΠΎΠ»Π΅Π·Π΅Π½ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΡŠΠΌ: сага, Π° ΠΏΠΎ-Ρ‚ΠΎΡ‡Π½ΠΎ сага Π½Π° Π±Π°Π·Π°Ρ‚Π° Π½Π° оркСстрация. Π‘ΡŠΡ‰Π½ΠΎΡΡ‚Ρ‚Π° ѝ Π΅ слСдната: ΠΈΠΌΠ° бизнСс сцСнарий, Π² ΠΊΠΎΠΉΡ‚ΠΎ Π΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ послСдоватСлно Π΄Π° сС ΠΈΠ·Π²ΡŠΡ€ΡˆΠ°Ρ‚ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ Π² Ρ€Π°Π·Π»ΠΈΡ‡Π½ΠΈ услуги, Π° Π² случай Π½Π° възникванС Π½Π° ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ Π½Π° ΠΊΠΎΠΉΡ‚ΠΎ ΠΈ Π΄Π° Π΅ Π΅Ρ‚Π°ΠΏ Π΅ Π½ΡƒΠΆΠ½ΠΎ Π΄Π° сС ΠΈΠ·Π²ΠΈΠΊΠ° ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π° Π·Π° отмяна Π½Π° всички ΠΏΡ€Π΅Π΄ΠΈΡˆΠ½ΠΈ ΡΡ‚ΡŠΠΏΠΊΠΈ, ΠΊΡŠΠ΄Π΅Ρ‚ΠΎ Π΅ ΠΏΡ€Π΅Π΄Π²ΠΈΠ΄Π΅Π½Π°. Π’Π°ΠΊΠ°, Π² края Π½Π° ΠΈΠ·ΠΏΡŠΠ»Π½Π΅Π½ΠΈΠ΅Ρ‚ΠΎ Π½Π° сага, нСзависимо ΠΎΡ‚ успСха, ΠΏΠΎΠ»ΡƒΡ‡Π°Π²Π°ΠΌΠ΅ консистСнтни Π΄Π°Π½Π½ΠΈ във всички Π΄ΠΎΠΌΠ΅ΠΉΠ½ΠΈ.

ΠΠ°ΡˆΠ°Ρ‚Π° рСализация Π΅ Π½Π°ΠΏΡ€Π°Π²Π΅Π½Π° Π² основСн Π²ΠΈΠ΄ ΠΈ Π½Π΅ Π΅ ΡΠ²ΡŠΡ€Π·Π°Π½Π° с ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅Ρ‚ΠΎ Π½Π° ΠΊΠ°ΠΊΠ²ΠΈΡ‚ΠΎ ΠΈ Π΄Π° Π΅ срСдства Π·Π° взаимодСйствиС с Π΄Ρ€ΡƒΠ³ΠΈΡ‚Π΅ услуги. ΠŸΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ ѝ Π½Π΅ Π΅ слоТно: Π΄ΠΎΡΡ‚Π°Ρ‚ΡŠΡ‡Π½ΠΎ Π΅ Π΄Π° сС създадС наслСдник ΠΎΡ‚ основния абстрактСн клас SagaBase, ΠΊΡŠΠ΄Π΅Ρ‚ΠΎ T – Ρ‚ΠΎΠ²Π° Π΅ Π²Π°ΡˆΠΈΡΡ‚ клас контСкст, Π² ΠΊΠΎΠΉΡ‚ΠΎ ΠΌΠΎΠ³Π°Ρ‚ Π΄Π° сС ΡΡŠΡ…Ρ€Π°Π½ΡΠ²Π°Ρ‚ ΠΈΠ·Ρ…ΠΎΠ΄Π½ΠΈ Π΄Π°Π½Π½ΠΈ, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΈ Π·Π° Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚Π° Π½Π° сага, ΠΊΠ°ΠΊΡ‚ΠΎ ΠΈ някои ΠΌΠ΅ΠΆΠ΄ΠΈΠ½Π½ΠΈ Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚ΠΈ. Π•ΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡ€ΡŠΡ‚ Π½Π° контСкста Ρ‰Π΅ бъдС ΠΏΡ€Π΅Π΄Π°Π²Π°Π½ Π½Π° всички ΡΡ‚ΡŠΠΏΠΊΠΈ ΠΏΠΎ Π²Ρ€Π΅ΠΌΠ΅ Π½Π° ΠΈΠ·ΠΏΡŠΠ»Π½Π΅Π½ΠΈΠ΅Ρ‚ΠΎ. Π‘Π°ΠΌΠ°Ρ‚Π° сага Π΅ stateless клас, Ρ‚Π°ΠΊΠ° Ρ‡Π΅ Π΅ΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡ€ΡŠΡ‚ ΠΌΠΎΠΆΠ΅ Π΄Π° бъдС поставСн Π² DI ΠΊΠ°Ρ‚ΠΎ Singleton, Π·Π° Π΄Π° ΠΏΠΎΠ»ΡƒΡ‡ΠΈ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΈΡ‚Π΅ зависимости.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ Π·Π° дСкларация:

public class ExampleSaga : SagaBase
{
  public ExampleSaga()
  {
    Step("Π‘Ρ‚ΡŠΠΏΠΊΠ° 1")
      .WithAction(c => ...)
      .WithCompensation(c => ...);
	
    AsyncStep("Π‘Ρ‚ΡŠΠΏΠΊΠ° 2")
      .WithAction(async c => ...);
  }
}

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ Π·Π° ΠΈΠ·Π²ΠΈΠΊΠ²Π°Π½Π΅:

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

Пълни ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΈ Π·Π° Ρ€Π°Π·Π»ΠΈΡ‡Π½ΠΈ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° Π²ΠΈΠ΄ΠΈΡ‚Π΅ Ρ‚ΡƒΠΊ. ΠΈ Π² сборка с тСстовС..

ViennaNET.Orm.*

Набор ΠΎΡ‚ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ Π·Π° Ρ€Π°Π±ΠΎΡ‚Π° с Ρ€Π°Π·Π»ΠΈΡ‡Π½ΠΈ Π‘Π” Ρ‡Ρ€Π΅Π· NHibernate. НиС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄Π° DB-First с ΠΏΡ€ΠΈΠ»Π°Π³Π°Π½Π΅ Π½Π° Liquibase, Π·Π°Ρ‚ΠΎΠ²Π° Ρ‚ΡƒΠΊ Π΅ Π½Π°Π»ΠΈΡ‡Π½Π° само функционалността Π·Π° Ρ€Π°Π±ΠΎΡ‚Π° с Π΄Π°Π½Π½ΠΈ Π² Π³ΠΎΡ‚ΠΎΠ²Π° Π‘Π”.

ViennaNET.Orm.Seedwork ΠΈ ViennaNET.Orm – основни ΡΡŠΠ±ΠΈΡ€Π°Π½ΠΈΡ, ΡΡŠΠ΄ΡŠΡ€ΠΆΠ°Ρ‰ΠΈ Π±Π°Π·ΠΎΠ²ΠΈ интСрфСйси ΠΈ Ρ‚Π΅Ρ…Π½ΠΈΡ‚Π΅ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΡΡŠΠΎΡ‚Π²Π΅Ρ‚Π½ΠΎ. НСка сС спрСм Π½Π° тях ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎ.

Π˜Π½Ρ‚Π΅Ρ€Ρ„Π΅ΠΉΡ IEntityFactoryService ΠΈ Π½Π΅Π³ΠΎΠ²Π°Ρ‚Π° рСализация EntityFactoryService са основната ΠΎΡ‚ΠΏΡ€Π°Π²Π½Π° Ρ‚ΠΎΡ‡ΠΊΠ° Π·Π° Ρ€Π°Π±ΠΎΡ‚Π° с Π‘Π”, Ρ‚ΡŠΠΉ ΠΊΠ°Ρ‚ΠΎ Ρ‚ΡƒΠΊ сС създава Unit of Work, Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π° Π·Π° Ρ€Π°Π±ΠΎΡ‚Π° с ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΈ ΡΡŠΡ‰Π½ΠΎΡΡ‚ΠΈ, ΠΊΠ°ΠΊΡ‚ΠΎ ΠΈ ΠΈΠ·ΠΏΡŠΠ»Π½ΠΈΡ‚Π΅Π»ΠΈ Π½Π° ΠΊΠΎΠΌΠ°Π½Π΄ΠΈ ΠΈ ΠΏΡ€Π΅ΠΊΠΈ SQL заявки. Понякога Π΅ ΡƒΠ΄ΠΎΠ±Π½ΠΎ Π΄Π° сС ΠΎΠ³Ρ€Π°Π½ΠΈΡ‡ΠΈ функционалността Π½Π° класа Π·Π° Ρ€Π°Π±ΠΎΡ‚Π° с Π‘Π”, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π΄Π° ΠΈΠΌΠ° Π²ΡŠΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ само Π·Π° Ρ‡Π΅Ρ‚Π΅Π½Π΅ Π½Π° Π΄Π°Π½Π½ΠΈ. Π—Π° Ρ‚Π°ΠΊΠΈΠ²Π° случаи IEntityFactoryService ΠΈΠΌΠ° ΠΏΡ€Π΅Π΄ΡˆΠ΅ΡΡ‚Π²Π΅Π½ΠΈΠΊ – интСрфСйс IEntityRepositoryFactory, Π² ΠΊΠΎΠΉΡ‚ΠΎ Π΅ обявСн само ΠΌΠ΅Ρ‚ΠΎΠ΄ Π·Π° създаванС Π½Π° Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π°.

Π—Π° Π΄ΠΈΡ€Π΅ΠΊΡ‚Π½ΠΎ ΠΎΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠ΅ към Π‘Π” сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΡŠΠΌ Π½Π° доставчици. Π—Π° всяка Π‘Π£Π‘Π”, която ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ Π² Π΅ΠΊΠΈΠΏΠΈΡ‚Π΅, ΠΈΠΌΠ° своя рСализация: ViennaNET.Orm.MSSQL, ViennaNET.Orm.Oracle, ViennaNET.Orm.SQLite, ViennaNET.Orm.PostgreSql.

Π’ ΡΡŠΡ‰ΠΎΡ‚ΠΎ Π²Ρ€Π΅ΠΌΠ΅ Π² Π΅Π΄Π½ΠΎ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅ Π΄Π° бъдС рСгистрирано няколко доставчици Π΅Π΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ, ΠΊΠΎΠ΅Ρ‚ΠΎ позволява, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π² Ρ€Π°ΠΌΠΊΠΈΡ‚Π΅ Π½Π° Π΅Π΄ΠΈΠ½ сСрвис Π±Π΅Π· Π½ΠΈΠΊΠ°ΠΊΠ²ΠΈ Ρ€Π°Π·Ρ…ΠΎΠ΄ΠΈ Π·Π° подобряванС Π½Π° инфраструктурата Π΄Π° сС ΠΏΡ€ΠΎΠ²Π΅Π΄Π΅ ΠΏΠΎΠ΅Ρ‚Π°ΠΏΠ½Π° миграция ΠΎΡ‚ Π΅Π΄Π½Π° Π‘Π£Π‘Π” Π½Π° Π΄Ρ€ΡƒΠ³Π°. ΠœΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΡŠΡ‚ Π·Π° ΠΈΠ·Π±ΠΎΡ€ Π½Π° Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎΡ‚ΠΎ ΡΠ²ΡŠΡ€Π·Π²Π°Π½Π΅ ΠΈ слСдоватСлно доставчика Π·Π° ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π΅Π½ клас-ΡΡŠΡ‰Π½ΠΎΡΡ‚ (Π·Π° ΠΊΠΎΠΉΡ‚ΠΎ сС пишС ΠΌΠ°ΠΏΠΈΠ½Π³ Π½Π° Ρ‚Π°Π±Π»ΠΈΡ†ΠΈ Π² Π‘Π”) Π΅ Ρ€Π΅Π°Π»ΠΈΠ·ΠΈΡ€Π°Π½ Ρ‡Ρ€Π΅Π· рСгистрация Π½Π° ΡΡŠΡ‰Π½ΠΎΡΡ‚Ρ‚Π° Π² класа BoundedContext (ΡΡŠΠ΄ΡŠΡ€ΠΆΠ° ΠΌΠ΅Ρ‚ΠΎΠ΄ Π·Π° рСгистрация Π½Π° Π΄ΠΎΠΌΠ΅ΠΉΠ½ ΡΡŠΡ‰Π½ΠΎΡΡ‚ΠΈ) ΠΈΠ»ΠΈ нСговия наслСдник ApplicationContext (ΡΡŠΠ΄ΡŠΡ€ΠΆΠ° ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΈ Π·Π° рСгистрация Π½Π° Π°ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΠΎΠ½Π½ΠΈ ΡΡŠΡ‰Π½ΠΎΡΡ‚ΠΈ, ΠΏΡ€Π΅ΠΊΠΈ заявки ΠΈ ΠΊΠΎΠΌΠ°Π½Π΄ΠΈ), ΠΊΡŠΠ΄Π΅Ρ‚ΠΎ Π² качСството Π½Π° Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ сС ΠΏΡ€ΠΈΠ΅ΠΌΠ° ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ΡŠΡ‚ Π½Π° ΡΠ²ΡŠΡ€Π·Π²Π°Π½Π΅Ρ‚ΠΎ ΠΎΡ‚ конфигурацията:

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

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ ApplicationContext:

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

Ако ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ΡŠΡ‚ Π½Π° ΡΠ²ΡŠΡ€Π·Π²Π°Π½Π΅Ρ‚ΠΎ Π½Π΅ Π΅ ΡƒΠΊΠ°Π·Π°Π½, Ρ‰Π΅ сС ΠΏΠΎΠ»Π·Π²Π° ΡΠ²ΡŠΡ€Π·Π²Π°Π½Π΅ с ΠΈΠΌΠ΅ Β«defaultΒ».

ΠœΠ°ΠΏΠΈΡ€Π°Π½Π΅Ρ‚ΠΎ Π½Π° ΠΎΠ±Π΅ΠΊΡ‚ΠΈ към Ρ‚Π°Π±Π»ΠΈΡ†ΠΈ Π² Π±Π°Π·Π°Ρ‚Π° Π΄Π°Π½Π½ΠΈ сС Ρ€Π΅Π°Π»ΠΈΠ·ΠΈΡ€Π° с стандартнитС срСдства Π½Π° NHibernate. ΠœΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚Π΅ описаниС ΠΊΠ°ΠΊΡ‚ΠΎ Ρ‡Ρ€Π΅Π· XML Ρ„Π°ΠΉΠ»ΠΎΠ²Π΅, Ρ‚Π°ΠΊΠ° ΠΈ Ρ‡Ρ€Π΅Π· класовС. Π—Π° ΡƒΠ΄ΠΎΠ±Π½ΠΎ написванС Π½Π° замСститСли Π½Π° Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΈΡ‚Π΅ Π² Unit тСстовСтС, Π΅ Π½Π°Π»ΠΈΡ‡Π½Π° Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° ViennaNET.TestUtils.Orm.

Пълни ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΈ Π·Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ Π½Π° ViennaNET.Orm.* ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° Π½Π°ΠΌΠ΅Ρ€ΠΈΡ‚Π΅ Ρ‚ΡƒΠΊ..

ViennaNET.Messaging.*

ΠšΠΎΠΌΠΏΠ»Π΅ΠΊΡ‚ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ Π·Π° Ρ€Π°Π±ΠΎΡ‚Π° с опашки.

Π—Π° Ρ€Π°Π±ΠΎΡ‚Π° с опашки Π΅ ΠΈΠ·Π±Ρ€Π°Π½ ΡΡŠΡ‰ΠΈΡΡ‚ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄, ΠΊΠ°ΠΊΡ‚ΠΎ с Ρ€Π°Π·Π»ΠΈΡ‡Π½ΠΈΡ‚Π΅ Π‘Π£Π‘Π”, Π° ΠΈΠΌΠ΅Π½Π½ΠΎ – максимално ΡƒΠ½ΠΈΡ„ΠΈΡ†ΠΈΡ€Π°Π½ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ ΠΎΡ‚ Π³Π»Π΅Π΄Π½Π° Ρ‚ΠΎΡ‡ΠΊΠ° Π½Π° Ρ€Π°Π±ΠΎΡ‚Π° с Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°Ρ‚Π°, нСзависимо ΠΎΡ‚ използвания ΠΌΠ΅Π½ΠΈΠ΄ΠΆΡŠΡ€ Π½Π° опашки. Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°Ρ‚Π° ViennaNET.Messaging Ρ‚ΠΎΡ‡Π½ΠΎ отговаря Π·Π° Ρ‚Π°Π·ΠΈ унификация, Π° ViennaNET.Messaging.MQSeriesQueue, ViennaNET.Messaging.RabbitMQQueue ΠΈ ViennaNET.Messaging.KafkaQueue ΡΡŠΠ΄ΡŠΡ€ΠΆΠ°Ρ‚ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Π½Π° Π°Π΄Π°ΠΏΡ‚Π΅Ρ€ΠΈ Π·Π° IBM MQ, RabbitMQ ΠΈ Kafka ΡΡŠΠΎΡ‚Π²Π΅Ρ‚Π½ΠΎ.

Π’ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚Π° с опашки ΠΈΠΌΠ° Π΄Π²Π° процСса: ΠΏΠΎΠ»ΡƒΡ‡Π°Π²Π°Π½Π΅ Π½Π° ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅ ΠΈ ΠΈΠ·ΠΏΡ€Π°Ρ‰Π°Π½Π΅.

НСка Ρ€Π°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ ΠΏΠΎΠ»ΡƒΡ‡Π°Π²Π°Π½Π΅Ρ‚ΠΎ. Има 2 Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Π°: Π·Π° постоянно ΡΠ»ΡƒΡˆΠ°Π½Π΅ ΠΈ Π·Π° ΠΏΠΎΠ»ΡƒΡ‡Π°Π²Π°Π½Π΅ Π½Π° Π΅Π΄ΠΈΠ½ΠΈΡ‡Π½ΠΎ ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅. Π—Π° постоянно ΡΠ»ΡƒΡˆΠ°Π½Π΅ Π½Π° ΠΎΠΏΠ°ΡˆΠΊΠ°Ρ‚Π°, ΠΏΡŠΡ€Π²ΠΎ трябва Π΄Π° опишСм клас Π½Π° процСсора, наслСдСн ΠΎΡ‚ IMessageProcessor, ΠΊΠΎΠΉΡ‚ΠΎ Ρ‰Π΅ отговаря Π·Π° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ°Ρ‚Π° Π½Π° входящото ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅. Π‘Π»Π΅Π΄ Ρ‚ΠΎΠ²Π° Π΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π΄Π° Π³ΠΎ "ΠΏΡ€ΠΈΠ²ΡŠΡ€ΠΆΠ΅Ρ‚Π΅" към ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π° опашка, ΠΊΠΎΠ΅Ρ‚ΠΎ става Ρ‡Ρ€Π΅Π· рСгистрация Π² IQueueReactorFactory с ΡƒΠΊΠ°Π·Π°Π½ΠΈΠ΅ Π·Π° ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€Π° Π½Π° ΠΎΠΏΠ°ΡˆΠΊΠ°Ρ‚Π° ΠΎΡ‚ конфигурацията:

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

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ Π·Π° стартиранС Π½Π° ΡΠ»ΡƒΡˆΠ°Π½Π΅Ρ‚ΠΎ:

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

Π‘Π»Π΅Π΄ Ρ‚ΠΎΠ²Π°, ΠΏΡ€ΠΈ стартиранС Π½Π° услугата ΠΈ ΠΈΠ·Π²ΠΈΠΊΠ²Π°Π½Π΅ Π½Π° ΠΌΠ΅Ρ‚ΠΎΠ΄Π° Π·Π° Π½Π°Ρ‡Π°Π»ΠΎ Π½Π° ΡΠ»ΡƒΡˆΠ°Π½Π΅Ρ‚ΠΎ, всички ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΡ ΠΎΡ‚ ΡƒΠΊΠ°Π·Π°Π½Π°Ρ‚Π° опашка Ρ‰Π΅ ΠΏΠΎΠΏΠ°Π΄Π°Ρ‚ Π² ΡΡŠΠΎΡ‚Π²Π΅Ρ‚Π½ΠΈΡ процСсор.

Π—Π° ΠΏΠΎΠ»ΡƒΡ‡Π°Π²Π°Π½Π΅ Π½Π° Π΅Π΄ΠΈΠ½ΠΈΡ‡Π½ΠΎ ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅ Π² интСрфСйса-Ρ„Π°Π±Ρ€ΠΈΠΊΠ° IMessagingComponentFactory ΠΈΠΌΠ° ΠΌΠ΅Ρ‚ΠΎΠ΄ CreateMessageReceiver, ΠΊΠΎΠΉΡ‚ΠΎ Ρ‰Π΅ създадС ΠΏΠΎΠ»ΡƒΡ‡Π°Ρ‚Π΅Π», ΠΎΡ‡Π°ΠΊΠ²Π°Ρ‰ ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅ ΠΎΡ‚ ΡƒΠΊΠ°Π·Π°Π½Π°Ρ‚Π° опашка:

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

Π—Π° ΠΈΠ·ΠΏΡ€Π°Ρ‰Π°Π½Π΅ Π½Π° ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅ Π΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π΄Π° сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π° ΡΡŠΡ‰Π°Ρ‚Π° IMessagingComponentFactory ΠΈ Π΄Π° сС създадС ΠΈΠ·ΠΏΡ€Π°Ρ‰Π°Ρ‡ Π½Π° ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΡ:

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

Π—Π° сСриализация ΠΈ дСсСриализация Π½Π° ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΡ ΠΈΠΌΠ° Ρ‚Ρ€ΠΈ Π³ΠΎΡ‚ΠΎΠ²ΠΈ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Π°: ΠΎΠ±ΠΈΠΊΠ½ΠΎΠ²Π΅Π½ тСкст, XML ΠΈ JSON, Π½ΠΎ ΠΏΡ€ΠΈ нСобходимост спокойно ΠΌΠΎΠΆΠ΅ Π΄Π° сС Π½Π°ΠΏΡ€Π°Π²ΠΈ свои Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Π½Π° интСрфСйситС IMessageSerializer ΠΈ IMessageDeserializer.

ΠžΠΏΠΈΡ‚Π°Ρ…ΠΌΠ΅ сС Π΄Π° Π·Π°ΠΏΠ°Π·ΠΈΠΌ ΡƒΠ½ΠΈΠΊΠ°Π»Π½ΠΈΡ‚Π΅ Π²ΡŠΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΠΈ Π½Π° всСки ΠΌΠ΅Π½ΠΈΠ΄ΠΆΡŠΡ€ Π½Π° опашки, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ViennaNET.Messaging.MQSeriesQueue позволява ΠΈΠ·ΠΏΡ€Π°Ρ‰Π°Π½Π΅ Π½Π΅ само Π½Π° тСкстови, Π½ΠΎ ΠΈ Π½Π° Π±Π°ΠΉΡ‚ΠΎΠ²ΠΈ ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΡ, Π° ViennaNET.Messaging.RabbitMQQueue ΠΏΠΎΠ΄Π΄ΡŠΡ€ΠΆΠ° ΠΌΠ°Ρ€ΡˆΡ€ΡƒΡ‚ΠΈΠ·ΠΈΡ€Π°Π½Π΅ ΠΈ създаванС Π½Π° опашки "Π½Π° Π»Π΅Ρ‚ΠΈΡ‰Π°". Π’ Π½Π°ΡˆΠ°Ρ‚Π° ΠΎΠ±Π²ΠΈΠ²ΠΊΠ° Π½Π° Π°Π΄Π°ΠΏΡ‚Π΅Ρ€Π° Π·Π° RabbitMQ ΡΡŠΡ‰ΠΎ Π΅ Ρ€Π΅Π°Π»ΠΈΠ·ΠΈΡ€Π°Π½Π° аналогия Π½Π° RPC: ΠΈΠ·ΠΏΡ€Π°Ρ‰Π°ΠΌΠ΅ ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅ ΠΈ ΠΎΡ‡Π°ΠΊΠ²Π°ΠΌΠ΅ ΠΎΡ‚Π³ΠΎΠ²ΠΎΡ€ ΠΎΡ‚ спСциална Π²Ρ€Π΅ΠΌΠ΅Π½Π½Π° опашка, която сС създава само Π·Π° Π΅Π΄Π½ΠΎ ΠΎΡ‚Π²Π΅Ρ‚Π½ΠΎ ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅.

Π•Ρ‚ΠΎ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π·Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ Π½Π° опашки с основни нюанси Π½Π° ΡΠ²ΡŠΡ€Π·Π²Π°Π½Π΅.

ViennaNET.CallContext

ИзползвамС опашки Π½Π΅ само Π·Π° интСграция ΠΌΠ΅ΠΆΠ΄Ρƒ Ρ€Π°Π·Π»ΠΈΡ‡Π½ΠΈ систСми, Π½ΠΎ ΠΈ Π·Π° ΠΎΠ±Ρ‰ΡƒΠ²Π°Π½Π΅ ΠΌΠ΅ΠΆΠ΄Ρƒ микросСрвизи Π² Π΅Π΄Π½ΠΎ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π² Ρ€Π°ΠΌΠΊΠΈΡ‚Π΅ Π½Π° сагата. Π’ΠΎΠ²Π° Π΄ΠΎΠ²Π΅Π΄Π΅ Π΄ΠΎ нСобходимостта ΠΎΡ‚ ΠΏΡ€Π΅Π΄Π°Π²Π°Π½Π΅ Π·Π°Π΅Π΄Π½ΠΎ с ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅Ρ‚ΠΎ Π½Π° Ρ‚Π°ΠΊΠΈΠ²Π° ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈ Π΄Π°Π½Π½ΠΈ, ΠΊΠ°Ρ‚ΠΎ Π»ΠΎΠ³ΠΈΠ½ Π½Π° потрСбитСля, ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ Π½Π° заявката Π·Π° прослСдяванС Π½Π° Π»ΠΎΠ³ΠΎΠ²Π΅, IP адрСс Π½Π° ΠΈΠ·Ρ‚ΠΎΡ‡Π½ΠΈΠΊΠ° ΠΈ Π΄Π°Π½Π½ΠΈ Π·Π° авторизация. Π—Π° рСализация Π½Π° ΠΏΡ€Π΅Π΄Π°Π²Π°Π½Π΅ Π½Π° Ρ‚Π΅Π·ΠΈ Π΄Π°Π½Π½ΠΈ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΈΡ…ΠΌΠ΅ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° ViennaNET.CallContext, която позволява ΡΡŠΡ…Ρ€Π°Π½Π΅Π½ΠΈΠ΅ Π½Π° Π΄Π°Π½Π½ΠΈ ΠΎΡ‚ входящата заявка Π² услугата. ΠŸΡ€ΠΈ Ρ‚ΠΎΠ²Π° Π½Π°Ρ‡ΠΈΠ½ΡŠΡ‚, ΠΏΠΎ ΠΊΠΎΠΉΡ‚ΠΎ Π΅ Π½Π°ΠΏΡ€Π°Π²Π΅Π½Π° заявката, ΠΏΡ€Π΅Π· опашка ΠΈΠ»ΠΈ ΠΏΡ€Π΅Π· Http, няма Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅. Π‘Π»Π΅Π΄ Ρ‚ΠΎΠ²Π°, ΠΏΡ€Π΅Π΄ΠΈ ΠΈΠ·ΠΏΡ€Π°Ρ‰Π°Π½Π΅ Π½Π° изходяща заявка ΠΈΠ»ΠΈ ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅, Π΄Π°Π½Π½ΠΈΡ‚Π΅ ΠΎΡ‚ контСкста сС ΠΈΠ·Π²Π»ΠΈΡ‡Π°Ρ‚ ΠΈ поставят Π² Π·Π°Π³Π»Π°Π²ΠΊΠΈΡ‚Π΅. Π’Π°ΠΊΠ° слСдващата услуга ΠΏΠΎΠ»ΡƒΡ‡Π°Π²Π° ΠΏΠΎΠΌΠΎΡ‰Π½ΠΈ Π΄Π°Π½Π½ΠΈ ΠΈ Π³ΠΈ управлява ΠΏΠΎ Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π΅Π½ Π½Π°Ρ‡ΠΈΠ½.

Π‘Π»Π°Π³ΠΎΠ΄Π°Ρ€ΠΈΠΌ Π·Π° Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅Ρ‚ΠΎ, ΠΎΡ‡Π°ΠΊΠ²Π°ΠΌΠ΅ Π²Π°ΡˆΠΈΡ‚Π΅ ΠΊΠΎΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈ ΠΈ pull request-ΠΎΠ²Π΅!

Π˜Π·Ρ‚ΠΎΡ‡Π½ΠΈΠΊ: habr.com

ΠšΡƒΠΏΠ΅Ρ‚Π΅ Π½Π°Π΄Π΅ΠΆΠ΄Π΅Π½ хостинг Π·Π° сайтовС със Π·Π°Ρ‰ΠΈΡ‚Π° ΠΎΡ‚ DDoS, VPS ΠΈ VDS ΡΡŠΡ€Π²ΡŠΡ€ΠΈ πŸ”₯ ΠšΡƒΠΏΠ΅Ρ‚Π΅ Π½Π°Π΄Π΅ΠΆΠ΄Π΅Π½ хостинг Π·Π° сайтовС със Π·Π°Ρ‰ΠΈΡ‚Π° ΠΎΡ‚ DDoS, VPS ΠΈ VDS ΡΡŠΡ€Π²ΡŠΡ€ΠΈ | ProHoster