10Things – Implementacja kontenera IoC

10Things - Implementacja kontenera IoC

Ciąg dalszy pracy na projektem 10Things. W dzisiejszym odcinku chciałbym opisać szczegóły implementacji kontenera IoC, oraz dalszy plan prac.

Implementacja kontenera IoC

W 10Things używam FreshMVVM, który ma zaimplementowany kontener IoC o nazwie FreshIoC. Pod spodem nie jest to nic innego jak TinyIoC ze zmienionymi namespace.

Jakie ma plus FreshIoC <-> TinyIoC?

  • Mały rozmiar – bibliotek FreshIoC waży tylko 42 Kb co czyni ją jedną z najlżejszych implementacji kontenera IoC
  • Prostota – robi tylko to co od niej oczekujemy, nie ma tutaj różnych „wodotrysków”
  • Szybkość – ze względu na rozmiar i prostotę jest bardzo szybki

Jakie ma minusy  FreshIoC < – > TinyIoC?

  • Wodotryski – brakuje w nim różnych zaawansowanych funkcjonalności kontenerów IoC

No dobra ale co sam autor twierdzi\pisze o tej bibliotece? Jako, że nie ma szczegółowego opisu FreshIoC będę się wspierał opisem TinyIoC.

Witaj TinyIoC

Welcome to TinyIoC – an easy to use, hassle free, Inversion of Control Container. TinyIoC has been designed to fulfil a single key requirement – to lower the „level of entry” for using an IoC container; both for small projects, and developers who are new to IoC who might be „scared” of the „big boys”!

To that end, TinyIoC attempts to stick to the following core principals:

  • Simplfied Inclusion – No assembly to reference, no binary to worry about, just a single cs file you can include in your project and you’re good to go. It even works with both Mono and MonoTouch for iPhone development!
  • Simplified Setup – With auto-resolving of concrete types and an „auto registration” option for interfaces setup is a piece of cake. It can be reduced to 0 lines for concrete types, or 1 line if you have any interface dependencies!
  • Simple, „Fluent” API – Just because it’s „Tiny”, doesn’t mean it has no features. A simple „fluent” API gives you access to the more advanced features, like specifying singleton/multi-instance, strong or weak references or forcing a particular constructor.

Tak autor określa funkcjonalność TinyIoC. Ale co nam po długich opisach, ahah i ochach nad biblioteką. Pora na porcję kodu jak tego w ogóle użyć.

Implementacja kontenera IoC. Mięcho, czyli Inversion Of Control po polsku

Mi osobiście bardziej podchodzi implementacja bez użycia Fluent API jak również wolę używać instancji jako Singleton.
Według Wiki Singleton to

Singleton – kreacyjny wzorzec projektowy, którego celem jest ograniczenie możliwości tworzenia obiektów danej klasy do jednej instancji oraz zapewnienie globalnego dostępu do stworzonego obiektu. Niekiedy wzorzec uogólnia się do przypadku wprowadzenia pewnej maksymalnej liczby obiektów, jakie mogą istnieć w systemie[1]. Niektórzy programiści uznają go za antywzorzec, ponieważ łamie zasady projektowania obiektowego, często bywa nadużywany[2] lub sprowadza się do stworzenia obiektowego zamiennika dla zmiennej globalnej[3][4].

Prosta rejestracja interfejsu w kontenerze

[code lang=”csharp”]
FreshIOC.Container.Register<IDataService, MockDataService); //As Singleton
FreshIOC.Container.Register<IUserDialogs>(UserDialogs.Instance); //As Singleton
[/code]

Można użyć również Fluent API do rejestracji

[code lang=”csharp”]
FreshIOC.Container.Register<IDataService, MockDataService>().AsSingleton();
FreshIOC.Container.Register<IUserDialogs>(UserDialogs.Instance).AsMultiInstance();
[/code]

Wstrzykiwanie zależności z użyciem konstruktora i nie tylko

W 10Things używam wstrzykiwania zależności za pomocą konstruktora co według mnie jest dobrą praktyką programistyczną. Znacznie lepszą niż użycie słówka Resolve.

Przykładem na użycie może być

[code lang=”csharp”]
public class MainViewPageModel
{
readonly IDataService dataService;
readonly IUserDialogs userDialogs;

public MainViewPageModel(IDataService dataService, IUserDialogs userDialogs)
{
this.dataService = dataService;
this.userDialogs = userDialogs;
}
}
[/code]

Można to również zaimplementować używając słówka Resolve.

[code lang=”csharp”]
public class MainViewPageModel
{
readonly IDataService dataService;
readonly IUserDialogs userDialogs;

public MainViewPageModel()
{
this.dataService = FreshIOC.container.Resolve<IDataService>();
this.userDialogs = FreshIOC.container.Resolve<IUserDialogs>();
}
}
[/code]

Jak widzicie użycie kontenera IoC nie musi być skomplikowane i trudne. Można to zrobić dużo prościej, przyjemniej. Podsumowując kontenerów Inversion Of Control jest tyle co grzybów po deszczu i każdy może znaleźć coś dla siebie. Ja wolę używać czegoś co jest lekkie i ma to co jest mi obecnie potrzebne.

10Things – co dalej

Będę rozwijał kolejne funkcjonalości aplikacji. Obecnie w planach mam dodanie obsługi menu (master detail), oraz stworzenie kontrolki kalendarza from scratch lub użycie gotowej. Chociaż wszystko wyjdzie w trakcie pracy.

Share