Ślub. Factory żeni się z IOC

Małżeństwo

Małżeństwo to nie taka prosta sprawa. Są różne i różnie się układają, różni ludzie się do tego mieszają czasem wychodzi to lepiej a czasem gorzej. Podobnie jest w programowaniu. Ostatnio musiałem ożenić IOC z Factory. Problem który się pojawił to tworzenie obiektu na podstawie jakiegoś tam parametru wejściowego, na początku miałem tylko jeden przypadek (np. RssChannel) i musiałem tylko ten przypadek obsługiwać, mogłem spokojnie wstrzyknąć handler i było cacy. Potem (w zasadzie teraz) mam drugi przypadek (Person) i na początku także wstrzykiwałem sobie handler dla tego przypadku. W ramach porządkowania robiłem małe poprawki w kodzie i nie mogłem przejść obok tego bez reakcji. Poza tym OCP patrzyło na mnie spode łba tak paskudnie.

Refactor

Zakasałem rękawy i wyrazałem wstrzykiwania do fabryki. Starej klasycznej fabryki, ja podaje parametr fabryka tworzy obiekt – ble! Wiecie operator new – brzydal. Posiadając chwile wolnego czasu postanowiłem pozbyć się new, skoro mam IOC i wszystko zarejestrowane marnotrawstwem będzie tworzenie obiektów samodzielnie przez new. Nie mówiąc o tym, że trzeba je skądś wziąć (te zależności), jeśli coś zmienię później, to będę musiał wrócić i poprawić,  no i to paskudne OCP – o matko ja patrzy i krzywi się.

Rekurencja

Teraz następuje chwila z którą każdy z nas się mierzy od czasu do czasu. Rekurencja. Jak zarejestrować Autofaca (z niego korzystam) jako zależność w samym sobie? Nie wiem, nie da się, nie umiem, suma summarum nie chce w kodzie zależeć w jawny sposób od Autofaca. #jakżyć Ale mogę zależeć od DependencyResolver – skoro pochodzi z frameworka nie będzie mnie to aż tak boleć. stuk-stuk-stuk coś napisałem. Nie działa, Resolver nie rozwiązuje zależności, trochę mam sens – zarejestrowałem go, a kilka linijek później nadpisuje go autofaciem:

DependencyResolver.SetResolver(new AutofacDependencyResolver(container));

W taki razie Lazy<T> – pierwszy raz w życiu mi się przyda. Ogień:

builder.RegisterType<SubscriptionHandlerFactory>()
.As<ISubscriptionHandlerFactory>()
.WithParameter(
new TypedParameter(typeof(Lazy<IDependencyResolver>),
new Lazy<IDependencyResolver>(() =>   DependencyResolver.Current)));

Jestę miszczem świata!

Rycerz

I wtedy on cały na biało: “You could use named and keyed service and retrieve instances using IIndex<TKey, TService>” – (chóry tle śpiewają teraz) aaaaaaaaaa. Jakie to piękne jest. I teraz właściwa treść posta:

Rejestracja wygląda tak:

@7 oraz @8 następuje rejestracja, gdzie jako konkretna implementacja jest dopięta do wartości enuma, a na końcu interfejs który ona implementuje.

Teraz samo “factory”:


Factory stało się nagle wraperem na konkretną implementacje kontenera zależności, teraz dzięki takiej sztuczki mogę łatwo testować kod, który zależy od fabryki.

Oraz klient:

Działa, gra i buczy

Klient fabryki, nic nie wie, skąd i jak i w zasadzie kto tworzy obiekty, ale jak sobie takie czytelnik pomyśli, to w zasadzie nie powinien wiedzieć i żyć w pięknym błogim stanie nieświadomości. Można się krzywić, że to serwis lokator, że OCP wciąż się lekko krzywi jak na to spogląda. Ale wiecie co, jak dla mnie to przecudownie rozwiązało problem, dynamicznego tworzenia obiektów, nie używania new, a wreszcie nie spinania się z konkretnym IOC.

3 thoughts on “Ślub. Factory żeni się z IOC

  1. Pingback: dotnetomaniak.pl

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.