ΠΠ±ΡΠ½ΠΎΡΡΡΠ° Π½Π° .NET ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΡΠΈΡΠ΅ Π½Π° Π Π°ΠΉΡΠ°ΠΉΠ·Π΅Π½Π±Π°Π½ΠΊ ΠΏΡΠΎΠ΄ΡΠ»ΠΆΠ°Π²Π° Ρ ΠΊΡΠ°ΡΡΠΊ ΠΎΠ±Π·ΠΎΡ Π½Π° ΡΡΠ΄ΡΡΠΆΠ°Π½ΠΈΠ΅ΡΠΎ Π½Π° ViennaNET. ΠΠ° ΡΠΎΠ²Π° ΠΊΠ°ΠΊ ΠΈ Π·Π°ΡΠΎ ΡΡΠΈΠ³Π½Π°Ρ ΠΌΠ΅ Π΄ΠΎ ΡΡΠΊ, .
Π ΡΠ°Π·ΠΈ ΡΡΠ°ΡΠΈΡ ΡΠ΅ ΡΠ°Π·Π³Π»Π΅Π΄Π°ΠΌΠ΅ ΠΎΡΠ΅ Π½Π΅ΡΠ°Π·Π³Π»Π΅Π΄Π°Π½ΠΈΡΠ΅ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ Π·Π° ΡΠ°Π±ΠΎΡΠ° Ρ ΡΠ°Π·ΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈ ΡΡΠ°Π½Π·Π°ΠΊΡΠΈΠΈ, ΠΎΠΏΠ°ΡΠΊΠΈ ΠΈ Π±Π°Π·ΠΈ Π΄Π°Π½Π½ΠΈ, ΠΊΠΎΠΈΡΠΎ ΠΌΠΎΠΆΠ΅ Π΄Π° Π½Π°ΠΌΠ΅ΡΠΈΡΠ΅ Π² Π½Π°ΡΠ΅ΡΠΎ Ρ ΡΠ°Π½ΠΈΠ»ΠΈΡΠ΅ Π² GitHub (), Π° .
ViennaNET.Sagas
ΠΠΎΠ³Π°ΡΠΎ ΠΏΡΠΎΠ΅ΠΊΡΡΡ ΠΏΡΠ΅ΠΌΠΈΠ½Π΅ Π½Π° DDD ΠΈ ΠΌΠΈΠΊΡΠΎΡΠ΅ΡΠ²ΠΈΡΠ½Π° Π°ΡΡ ΠΈΡΠ΅ΠΊΡΡΡΠ°, ΡΠ°Π·ΠΏΡΠ΅Π΄Π΅Π»ΡΠ½Π΅ΡΠΎ Π½Π° Π±ΠΈΠ·Π½Π΅Ρ Π»ΠΎΠ³ΠΈΠΊΠ°ΡΠ° Π² ΡΠ°Π·Π»ΠΈΡΠ½ΠΈ ΡΡΠ»ΡΠ³ΠΈ ΡΡΠ·Π΄Π°Π²Π° ΠΏΡΠΎΠ±Π»Π΅ΠΌ, ΡΠ²ΡΡΠ·Π°Π½ Ρ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎΡΡΡΠ° ΠΎΡ ΡΠ΅Π°Π»ΠΈΠ·ΠΈΡΠ°Π½Π΅ΡΠΎ Π½Π° ΠΌΠ΅Ρ Π°Π½ΠΈΠ·ΡΠΌ Π·Π° ΡΠ°Π·ΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈ ΡΡΠ°Π½Π·Π°ΠΊΡΠΈΠΈ, ΡΡΠΉ ΠΊΠ°ΡΠΎ ΠΌΠ½ΠΎΠ³ΠΎ ΡΡΠ΅Π½Π°ΡΠΈΠΈ ΡΠ΅ΡΡΠΎ Π·Π°ΡΡΠ³Π°Ρ Π½ΡΠΊΠΎΠ»ΠΊΠΎ Π΄ΠΎΠΌΠ΅ΠΉΠ½Π°. Π‘ ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΈ ΠΌΠ΅Ρ Π°Π½ΠΈΠ·ΠΌΠΈ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΠΏΠΎ-ΠΏΠΎΠ΄ΡΠΎΠ±Π½ΠΎ Π΄Π° ΡΠ΅ Π·Π°ΠΏΠΎΠ·Π½Π°Π΅ΡΠ΅, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, .
Π Π½Π°ΡΠΈΡΠ΅ ΠΏΡΠΎΠ΅ΠΊΡΠΈ ΡΠ΅Π°Π»ΠΈΠ·ΠΈΡΠ°Ρ ΠΌΠ΅ ΠΏΡΠΎΡΡ, Π½ΠΎ ΠΏΠΎΠ»Π΅Π·Π΅Π½ ΠΌΠ΅Ρ Π°Π½ΠΈΠ·ΡΠΌ: ΡΠ°Π³Π°, Π° ΠΏΠΎ-ΡΠΎΡΠ½ΠΎ ΡΠ°Π³Π° Π½Π° Π±Π°Π·Π°ΡΠ° Π½Π° ΠΎΡΠΊΠ΅ΡΡΡΠ°ΡΠΈΡ. Π‘ΡΡΠ½ΠΎΡΡΡΠ° Ρ Π΅ ΡΠ»Π΅Π΄Π½Π°ΡΠ°: ΠΈΠΌΠ° Π±ΠΈΠ·Π½Π΅Ρ ΡΡΠ΅Π½Π°ΡΠΈΠΉ, Π² ΠΊΠΎΠΉΡΠΎ Π΅ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»Π½ΠΎ Π΄Π° ΡΠ΅ ΠΈΠ·Π²ΡΡΡΠ°Ρ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ Π² ΡΠ°Π·Π»ΠΈΡΠ½ΠΈ ΡΡΠ»ΡΠ³ΠΈ, Π° Π² ΡΠ»ΡΡΠ°ΠΉ Π½Π° Π²ΡΠ·Π½ΠΈΠΊΠ²Π°Π½Π΅ Π½Π° ΠΏΡΠΎΠ±Π»Π΅ΠΌ Π½Π° ΠΊΠΎΠΉΡΠΎ ΠΈ Π΄Π° Π΅ Π΅ΡΠ°ΠΏ Π΅ Π½ΡΠΆΠ½ΠΎ Π΄Π° ΡΠ΅ ΠΈΠ·Π²ΠΈΠΊΠ° ΠΏΡΠΎΡΠ΅Π΄ΡΡΠ° Π·Π° ΠΎΡΠΌΡΠ½Π° Π½Π° Π²ΡΠΈΡΠΊΠΈ ΠΏΡΠ΅Π΄ΠΈΡΠ½ΠΈ ΡΡΡΠΏΠΊΠΈ, ΠΊΡΠ΄Π΅ΡΠΎ Π΅ ΠΏΡΠ΅Π΄Π²ΠΈΠ΄Π΅Π½Π°. Π’Π°ΠΊΠ°, Π² ΠΊΡΠ°Ρ Π½Π° ΠΈΠ·ΠΏΡΠ»Π½Π΅Π½ΠΈΠ΅ΡΠΎ Π½Π° ΡΠ°Π³Π°, Π½Π΅Π·Π°Π²ΠΈΡΠΈΠΌΠΎ ΠΎΡ ΡΡΠΏΠ΅Ρ Π°, ΠΏΠΎΠ»ΡΡΠ°Π²Π°ΠΌΠ΅ ΠΊΠΎΠ½ΡΠΈΡΡΠ΅Π½ΡΠ½ΠΈ Π΄Π°Π½Π½ΠΈ Π²ΡΠ² Π²ΡΠΈΡΠΊΠΈ Π΄ΠΎΠΌΠ΅ΠΉΠ½ΠΈ.
ΠΠ°ΡΠ°ΡΠ° ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ Π΅ Π½Π°ΠΏΡΠ°Π²Π΅Π½Π° Π² ΠΎΡΠ½ΠΎΠ²Π΅Π½ Π²ΠΈΠ΄ ΠΈ Π½Π΅ Π΅ ΡΠ²ΡΡΠ·Π°Π½Π° Ρ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ΡΠΎ Π½Π° ΠΊΠ°ΠΊΠ²ΠΈΡΠΎ ΠΈ Π΄Π° Π΅ ΡΡΠ΅Π΄ΡΡΠ²Π° Π·Π° Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡΠ²ΠΈΠ΅ Ρ Π΄ΡΡΠ³ΠΈΡΠ΅ ΡΡΠ»ΡΠ³ΠΈ. ΠΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ΡΠΎ Ρ Π½Π΅ Π΅ ΡΠ»ΠΎΠΆΠ½ΠΎ: Π΄ΠΎΡΡΠ°ΡΡΡΠ½ΠΎ Π΅ Π΄Π° ΡΠ΅ ΡΡΠ·Π΄Π°Π΄Π΅ Π½Π°ΡΠ»Π΅Π΄Π½ΠΈΠΊ ΠΎΡ ΠΎΡΠ½ΠΎΠ²Π½ΠΈΡ Π°Π±ΡΡΡΠ°ΠΊΡΠ΅Π½ ΠΊΠ»Π°Ρ 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
