Programowanie Reaktywne - Szpryca - AutoFac.

13.03.2018


Artykuł ten jest częścią serii artykułów na temat Programowania reaktywnego.

Zapraszam na GitHub-a.

Tematy

  1. Wstęp
  2. Zabawa z czasem - Timer
  3. Kto za tym stoi? - Scheduler
  4. Nie zapominaj - Subscribe
  5. Zabawa z czasem - Interval
  6. Zabawa z czasem - Buffer
  7. Zabawa z czasem - Delay
  8. Zabawa z czasem - Sample
  9. Zabawa z czasem - Throttle
  10. Zabawa z czasem - Timestamp/TimeInterval
  11. Tworzymy dane - Generators
  12. Tworzymy dane - Własna klasa publikująca
  13. Marudzimy - Skip
  14. Marudzimy - Take
  15. Łap To! - ConsoleKey
  16. Kombinatorzy - Concat
  17. Kombinatorzy - Repeat
  18. Kombinatorzy - Start With
  19. Kombinatorzy - Ambiguous
  20. Kombinatorzy - Merge
  21. Kombinatorzy - Zip
  22. Kombinatorzy - Switch
  23. Kombinatorzy - When-And-Then
  24. Kombinatorzy - Combine Latest
  25. Transformers - Select
  26. Transformers - OfType and Cast
  27. Transformers - Metadata
  28. Bileciki do kontroli - Unit Tests of Interval
  29. Bileciki do kontroli - Unit Tests of Observer Interval
  30. Bileciki do kontroli - Unit Tests of Create Cold/Hot Observable
  31. Szpryca - AutoFac

Wstęp

Reactive Extensions - AutoFac Ludzie lubią ułatwiać sobie życie. Programiści to też podobno ludzie ;) dlatego pewnie postępują podobnie. Czasem z lenistwa, innym razem z własnych nieprzymuszonych chęci. Branża IT nieustannie się rozwija. Powstają takie wspaniałości jak wstrzykiwanie zależności;)

Warto było by i w rodzinie Rx-owatych dostawać to co się chce i kiedy się chce.

AutoFac

Hmm posłużę się tutaj moją ulubioną biblioteką do wstrzykiwania szprycy w konstruktorach. AutoFac. Nie ma róży bez kolców… By ktoś miał lepiej inny musi mieć gorzej. Dlatego wszystkie wstrzykiwane środki trzeba wcześniej przygotować. Kontener trzeba załadować przed podróżą. Przykładowo rejestrujemy obiekt Interval. Niestety w tej formie możemy dokonać jedynie jednorazowej rejestracji. Wynika to z faktu, że musimy zidentyfikować ten tworzony obiekt, i dzieje się to poprzez IObservable<long>.

1
2
3
4
5
6
7
8
9
10
11
var builder = new ContainerBuilder();

builder
  .Register(c => Observable.Interval(TimeSpan.FromMilliseconds(100)))
  .As<IObservable<long>>()
  .SingleInstance();

builder.RegisterType<ObservableTimeCounter>().SingleInstance();

builder.RegisterType<Clock>();
builder.RegisterType<Part>();

Rejestrujemy także w ten sposób kilka innych obiektów, np. ObservableTimeCounter, Clock, Part.

Obiekty Rx-owe będą wstrzykiwane wielokrotnie, dlatego dobrze by je było zrobić jako Singleton-y.

Jak już sobie porejestrujemy obiekty. To można je powyciągać.

1
2
3
4
5
6
7
8
var container = InitContainer();

container.Resolve<Clock>();

for (var i = 0; i < 7; i++)
{
  container.Resolve<Part>();
}

Dla przykładu użyjemy obiektu Clock do wyświetlania zegara. Oraz kilu obiektów Part. Ale dzięki singleton-kom możemy wielokrotnie się podpinać pod zarejestrowane czasowe wyzwalacze.

A jak poprosić o obiekt Rx-a. Tak jak każdy inny:p, wykorzystując uchwyt do zarejestrowanego w kontenerze obiektu.

1
2
3
4
5
6
7
8
9
public Clock(ObservableTimeCounter interval, Object obj)
{
  _obj = obj;

  interval.Subscribe(time =>
  {
    lock (_obj)
    {
      Console.SetCursorPosition(Console.WindowWidth - 8, 0);

Reactive Extensions - Dependency Injection

Wstrzyknięty został obiekt ObservableTimeCounter, można już się zarejestrować.

Jest tutaj jeszcze jeden trik, jaki musiałem zastosować ze względu na pisanie na konsole. Obiekt, wstrzykiwany może być wykorzystywany w wielu miejsca. A służ on blokowaniu dostępu do określonego obszaru sekcji krytycznej.

W przeciwnym wypadku byłby niezły bajzel. Im więcej byśmy dodali obiektów, tym częściej działy by się cuda na ekranie konsoli. A to dlatego, że działania na konsoli: np.:

  • Console.SetCursorPosition - ustawienie pozycji kursora,
  • Console.WriteLine - wypisanie na konsole danych.

Łącznie nie są to działania atomowe. I poprzez korzystanie ze strumienia i wielu subskrypcjom sekwencja wykonania działań na konsoli, może być losowa. Dzięki zablokowaniu działania na konsoli. Sytuacja została w prosty sposób ogarnięta. Jednak nie jest to dobra praktyka i ma na celu jedynie prezentację działania Rx-ów i AutoFac-a.

1
2
3
4
5
6
7
8
public Part(IObservable<long> interval, Object obj)
{
  _obj = obj;
  _guid = Guid.NewGuid().ToString().Substring(0, 5);
  _top = count;
  count++;

  interval.Subscribe(OnNext);

Zakończenie

Oczywiście istnieje inne wyjście z problemu rejestrowania wielu obiektów np. Interval. Ale o tym myślę przy następnej okazji.

Kod z Wami!


Jest to post wchodzący w skład podjętego wyzwania ogłoszonego przez MIROBURN we vlogu z dnia 3 lutego 2018 roku.

Celem wyzwania jest systematyczne działanie w ciągu 30 dni.

Postanowiłem pisać post dziennie o tematyce Programowania Reaktywnego dla platformy .NET.

Wszelkie źródła związane z postami znajdują się na repozytorium GitHub.

Stan obecny wyzwania: 30 z 30 dni.


Referencje:


Wcześniejszy: Programowanie Reaktywne - Bileciki do kontroli - Unit Tests of Create Cold/Hot Observable


Zapisz się na listę :)