Zmiana biblioteki logów
Już na samym począteczku problemy, musiałem wymienić bibliotekę logów z log4net na NLog, okazało się, iż w moim projekcie opartym na .NET 4.5.2 nie można wykorzystać biblioteki log4net i tyle z nauki.
Oczywiście, żeby było śmieszniej dowiedziałem się o tym po konfiguracji, instalacji w sytuacji wystąpienia problemu z zapisem logów, czyli X czasu poszło się paść.
Autofac - kontenerek na moje śmieci
 Kolejno przyszedł czas na wdrożenie DIP (Dependency Inversion Principle) przy wykorzystaniu Dependency Injection. Do tego po instalacji pakietu trzeba trochę popracować nad szkieletem wykorzystującym Autofac-a.
Kolejno przyszedł czas na wdrożenie DIP (Dependency Inversion Principle) przy wykorzystaniu Dependency Injection. Do tego po instalacji pakietu trzeba trochę popracować nad szkieletem wykorzystującym Autofac-a.
A czym jest taki kontenerek? To bardzo proste, to składowisko obiektów naszej aplikacji. Trzeba go załadować w sposób jaki się chcę. A potem już tylko korzystać.
Realizuje fragment zasad SOLID, a dokładnie ostatnią literkę.
Zasada DIP określa, iż obiekty nie powinny być tworzone na żądanie, a wstrzykiwane z zewnątrz. Dzięki czemu zależność obiektu wykorzystującego inne klasy jest odwrócona. Określamy jakie klasy/interfejsy chcemy otrzymać, a kontener je dostarczy.
Dobra rada dla programisty - bądź SOLIDny.
Poniżej klasa statyczna implementująca ładowanie modułów kontenera.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
using System.Linq;
using Autofac;
using Autofac.Core;
namespace PictOgr.Core.AutoFac
{
    public static class Container
    {
        public static ContainerBuilder CreateBuilder()
        {
            var builder = new ContainerBuilder();
            LoadModules(builder);
            return builder;
        }
        private static void LoadModules(ContainerBuilder builder)
        {
            var types = AppDomain.CurrentDomain.GetAssemblies()
                .SelectMany(x => x.GetTypes())
                .Where(t => 
                    t.IsAssignableTo() 
                    && t.IsClass 
                    && !t.IsAbstract);
            foreach (var type in types)
            {
                builder.RegisterModule((IModule) Activator.CreateInstance(type));
            }
        }
    }
}
 Kontener można ładować parami, nie trzeba używać jednej łopaty. Można dodawać wiele ładując je automatycznie, za to odpowiedzialny jest zaznaczony fragment kodu.
 
Kontener można ładować parami, nie trzeba używać jednej łopaty. Można dodawać wiele ładując je automatycznie, za to odpowiedzialny jest zaznaczony fragment kodu.
Polega to na przeszukaniu wszystkich klas w aplikacji i wyciągnięciu ich typów spełniających wskazane warunki.
Ładowanie moich śmieci
Z kolei kod poniżej to modulik, mały jest i w tym przypadku ładuje wszystkie zależności dla NLoga. Po wykonaniu tego kodu w programie można wstrzykiwać loggera.
Oczywiście można rejestrować w kontenerze dowolne klasy np. builder.RegisterType<SplashScreenView>();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
using Autofac;
using Autofac.Extras.NLog;
namespace PictOgr.Core
{
    public class CoreModule : Module
    {
        protected override void Load(ContainerBuilder builder)
        {
            base.Load(builder);
			
            builder.RegisterModule();
        }
    }
}
Moduły tworzymy zazwyczaj w obszarach powiązanych razem z klasami jakie są ładowane. Unikamy tym samym zwalenia tworzenie wszystkich obiektów w jednym miejscu, czyli porządeczek.
Używanie kontenera
Po załadowaniu fajnie byłoby użyć Autofaca, ale wiadomo wszystko ma swój początek i koniec, dlatego należy zainicjować kontener. W moim przypadku będzie to w głównej klasie App.
L.12 tworzy kontener, czyli ładuje wszystkie moduliki z PictOgr-a.
Linia niżej to wyciągnięcie obiektu z kontenera, w tym przypadku okna powitalnego SplashScreenView.
Rejestrowanie obiektów w kontenerze, przy starcie aplikacji.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
using System.Windows;
using Autofac;
using PictOgr.Core.AutoFac;
using PictOgr.SplashScreen.Views;
namespace PictOgr
{
	public partial class App : Application
	{
		private void OnStartup(object sender, StartupEventArgs e)
		{
			var container = Container.CreateBuilder().Build();
			var splashScreenView = container.Resolve();
			splashScreenView.Show();
		}
	}
}

Jednak w tym przypadku żądamy od kontenera konkretnego obiektu, nie różni się to za bardzo od klasycznego podejścia, czyli new Klasa(), dlatego DI wykonywać będziemy w następujący sposób:
Wstrzykiwanie zależności.
1
2
3
4
5
6
7
8
9
public class StartApplicationCommand : ICommand
{
		private readonly MainWindowView mainWindowView;
		public StartApplicationCommand(MainWindowView mainWindowView)
		{
			this.mainWindowView = mainWindowView;
		}
        ...
Dotyczy to klasy MainWindowView, nigdzie nie jest ona tutaj tworzona, jest otrzymywana jako atrybut konstruktora, biblioteka Autofac wstrzykuje tą zależność.
Ogromne możliwości
Autofac jest bardzo rozbudowaną biblioteką, pozwala w różny sposób tworzyć obiekty, zbudowany jest na bazie wzorca projektowego Fluent Interface, który to pozwala na kaskadowe wywoływanie metod z klasy macierzystej. Każda metoda zwraca referencję do klasy, tym samym bazujemy na jednej klasie i wykonujemy na niej operacje.
Zastosowanie fluenta daje możliwość zapisu kolejnych etapów rejestrowania klasy z wykorzystaniem separacji kropką.
builder.RegisterType<TestClass>().As<ITestClass>();
W powyższym przykładzie rejestrujemy klase TestClass jako interfejs ITestClass.
Możemy także określić, iż klasa ma mieć tylko jedną instancję (Wzorzec Singleton) poprzez dopisanie
builder.RegisterType<TestClass>().As<ITestClass>().SingleInstance();
Można zarejestrować klasę samodzielnie ją tworząc, taką operację wykonujemy poniższym poleceniem:
builder.RegisterInstance(new TestClass()).As<ITestClass>();
Poniższy kodzik pokazuje, że można wykonać metodę w tworzonym obiekcie zaraz po jej utworzeniu.
builder.RegisterType<TestClass>().As<ITestClass>().OnActivated(e => e.Instance.Test());
Teraz to już pozostaje tylko „wstrzykiwać”… zależności 😉
Na dzisiaj tyle. Jestem w implementacji testów i CQRSa.
Liczę na konstruktywne komentarze:).
Jest to post przygotowany na potrzeby konkursu „Daj Się Poznać 2017” organizowanym przez Macieja Aniserowicza.
| Blog | https://mrdev.pl | 
| Projekt | https://mrdev.pl/pictogr-pomysl | 
| GitHub | github.com/krzysztofowsiany/pictogr | 
| Snapchat | www.snapchat.com/add/gocom7 | 
| www.facebook.com/PictOgr-1729700930654225 | |
| twitter.com/gemu_gocom | |
| RSS | http://mrdev.pl/category/daj-sie-poznac-2017/feed | 
 
    

 
     
      