MR. Dev

Blog programisty.

Programowanie Reaktywne - Transformers - Metadata.


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 - Materialize Dzisiejszym bohaterem zostaje ostatnia para Transformers-ów. Są oni ze sobą ściśle powiązani. Można śmiało powiedzieć, żę występują między nimi relacje rodzinne. Rodzic i dziecko. Zapraszam do dalszego czytania w celu zgłębienia tajemnic rodzinnych;).

Materialize i Dematerialize

Przygotowałem trzy przykłady. Na początek przygotujemy strumienie, i przekażemy je do metod zawierających mięsko.

1
2
3
4
5
6
7
8
9
var subscribents = new List<IDisposable>();
var observableProvider = new ObservableProvider();
var observableStream = GeneratorFactory.CreateGenerator(0, 5, 1, 300);

Console.WriteLine("Press any keys (Enter to end stream).");

MetadataCreateGenerator(subscribents, observableStream);
MetadataManual(subscribents);
MetadataConsoleKey(subscribents, observableProvider);

Reactive Extensions - Dematerialize W każdym z poniższych przykładów został użyty operator rodzica: Materialize. A dlaczego nazwałem go rodzicem? Tak samo jak dziecko musi mieć swojego rodzica podobnie jest z drugą metodą Dematerialize.

Podsumowując by użyć Dematerialize należy najpierw skorzystać z Materialize.

Powyższe metody wyświetlają dane w formie metadanych. Czyli ukazują w przypadku Materialize metodę jaka jest wywoływana oraz dane jakie zawiera. Oczywiście to jakie dane są wyświetlane zależy od strumienia. Jeżeli na strumień wrzucane są np. klasy. To wówczas nie otrzymamy jedynie nazwę klasy.

Druga metoda Dematerialize sięga głębiej i wyświetla jedynie parametry przekazane do metod: OnNext, OnError, OnCompleted.

Poniższy przykład dotyczy wykorzystania prezentacji w kontekście strumienia ConsoleKey.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private static void MetadataConsoleKey(ICollection<IDisposable> subscribents, ObservableProvider observableProvider)
{
  subscribents.Add(
    observableProvider.ConsoleKey
      .Materialize()
      .DefaultPrint("MaterializeConsoleKey"));

  subscribents.Add(observableProvider.ConsoleKey
    .Materialize()
    .Dematerialize()
    .DefaultPrint("DematerializeConsoleKey"));

  subscribents.Add(observableProvider.ConsoleKey
    .Select(x => x.Key)
    .DefaultPrint("ConsoleKey"));

Po wduszeniu klawisza na klawiaturze, wyświetli się dwie formy metadanych oraz faktyczny klawisz jaki został wduszony.

Drugi przykład jest prostszy i bazuje na strumieniu pochodzącym z Generatora. W tym przypadku podobnie wyświetlone zostaną dane oraz metadane.

1
2
3
4
5
6
7
8
9
private static void MetadataCreateGenerator(ICollection<IDisposable> subscribents,IObservable<int> observableStream)
{
  subscribents.Add(observableStream.Materialize()
    .DefaultPrint("MaterializeCreateGenerator"));

  subscribents.Add(observableStream
    .Materialize()
    .Dematerialize()
    .DefaultPrint("DematerializeCreateGenerator"));

Ostatni z przykładów jaki przygotowałem dotyczy manualnie generowanego strumienia. I tutaj możemy zaobserwować jak zostanie potraktowany wyjątek i wywołanie OnError.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
private static void MetadataManual(ICollection<IDisposable> subscribents)
{
  var source = new Subject<string>();

  source.Materialize()
    .DefaultPrint("MaterializeManual");

  source.Materialize()
    .Dematerialize()
    .DefaultPrint("DematerializeManual");

  source.OnNext("Tekst 1");
  source.OnNext("Tekst 2");

  source.OnError(new Exception("Wyjątek"));
  source.OnCompleted();

W powyższym przykładzie wykorzystane zostały wszystkie metody jakie zostały zaimplementowane z interfejsu: IObserver.

Zakończenie

Powyższe operatory mogą być bardzo przydatne do analizy problemów. Można zalogować jakie typy danych zostały wtłoczone na strumień. W innym kontekście nie widzę zastosowania: Materialize, Dematerialize.

Dziękuję za czytactwo i zapraszam do śledzenia moich blogowych poczynań…


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 - Transformers - OfType and Cast

Następny: Programowanie Reaktywne - Bileciki do kontroli - Unit Tests of Interval