Tuesday, July 5, 2016

Inversion Of Control - Unity

Those are the notes on "Inversion Of Control" course on Pluralsight.com by John Somnez related to Unity.
If you want to see the entire course or itself by details, please feel free to go on pluralsight.com

Some vocabulary:

   Dependency Inversion Principle (DIP) - Principle used in software architecture saying you would invert the way how the objects are constructed.

   Inversion Of Control (IoC) - Is a pattern to implement the Dependency Inversion Principle and it is used also for other principles. But it is how to invert interfaces, flow and dependencies.
   Dependency Injection (DI) - Is an implementation of a specific inversion of control pattern. 
   Inversion of Control Container - The framework to be used.

Dependency Inversion





   The high level class should may have some code in it in order to handle the dependencies and differences between low level classes.  
    Because the low level classes are defining the interfaces and high level class should know about how to use it, the high level class is not reusable.
    Consider each interface is different.




   We just moved the interface above the line. So, the interface now is defined by upper layer.
   The main concept is the low level class should conform with the interface.
   Comparing with the previous implementation, we could have many implementation of that interface, but high level class will not care.
   So, initially we had a high level class depending by low level classes and their implicit interfaces. Now, high level classes become reusable.
   According to Bob Martin (which defined this concept) there are some assumptions:
   a. High level modules should not depend by low level modules. Both of them should depend by abstractions.
   b. Abstractions should not depend upon details. Details should depend upon abstractions. With other words, the interfaces should be enough general to keep all information to implement one.
   An interface should be defined externally and both high and low classes to depend of them. 

Layering of an application
   If an application was initially developed as following layers: Policy -> Mechanism -> Utility, a change in layer Utility might affect changes in Mechanism and in Policy. What Bob Martin promoted is: Policy -> Mechanism Interface -> Mechanism interface (implementation ) -> Utility Interface -> Utility interface (implementation).

Inversion of Control
   Many different ideas. But basically is a pattern to apply the principle of dependency injection. It is a very broad concept.
   Long story short:





   Dependecy Inversion is a principle: classes to depend by abstractions. The Dependency Inversion is a principle implemented through a pattern: Inversion of Control. It has 3 flavours:
1. Interface inversion;
2. Flow inversion;
3. Dependency Creation (Binding inversion).
- There are many ways to do that. One of them is called Dependency Injection. That represents the implementation of the pattern of the principle.
   In order to make sense, when you implement an interface, you should have more implementations of that interface. Otherwise... what is the purpose of doing in this way ?

Interface inversion


 Instead to have an implementation for each provider, the consumer will have a single implementation through an abstraction (in this case an interface).

In interface inversion, the interface should be implemented by Provider and not by consumer.



Flow inversion
   It is a simple idea to invert the flow. So, if the application is telling you as user what to do, the flow inversion means to tell you to the application what to do. And that is usually happening via graphic user interfaces.

Dependency Creation / Binding Inversion
   If you create the object inside the class that is using it, then this is not dependency injection.
Inverting the object creation means to create the classes outside of the class where they are used.
   There are many types of Creation Inversion:
      1. Factory Pattern
                   Button button = ButtonFactory.CreateButton();

      2. Service Locator
                   Button button = ServiceLocator.Create (IButton.Class);

      3. Dependency Injection
                   Button button = GetTheRightButton();
                   OurScreen ourScreen = new OurScreen (button);

      4. More...

   What is: Is a type of Inversion of Control that move the creation and binding of a dependency outside of the class that depends on it.
   So, in a way or other, if we have:

 
So, using the dependency inversion principle, the DependencyClass is implementing the IDependency interface and it will be used by MyClass.

But... from somewhere or somehow, we still need the Dependency object. And we can't create it inside MyClass without violating the principle.

The dotted line represents the question: from where the dependency is coming from.





    In this way, the situation becomes:





So, an idea is to use another class known as Injector that is acting as an Injector.

The injector knows about my class, my dependency, interfaces. It is the injector responsibility to bind those things together.

So, when you are using dependency injector you should have something that is doing the injection. Also, that injector is important for all classes in the same situation. 





    There are few ways of injection:

    a) Constructor Injection
        - the most common and simple: it passes the dependency in the constructor of the dependent classes




   In this way, on constructor, the ICreditCard object is passed in. And also it will be kept in that class as a dependency.

    The good think is you are not able to create a class without dependencies.
    b) Setter Injection
        - Use setter instead of constructor. The down side is you could create a class without specifying all required setters (dependencies).
        - It allows us to create and use a class even without dependencies. It gives us flexibility. But in the same way it creates also danger to use a class without knowing if the dependency was set.
        - The example for using a setter injection:


   
    c) Interface Injection
       - Dependent class will implement an interface
       - Injector uses the interface to inject the dependency.
       - It is a little bit uncommon. 


   There is an interface IDependOnCreditCard which has a single method. There is the secret.
       - It is like a setter. The difference is to use an interface which has a method that known how to use it.

Warnings related to Dependency Injection
     1. Leaks the internal implementation details of a class.
          - It violates encapsulation: because it takes the internal implementation and exposes it through constructor of the class.
     2. Prevent deferred creation
          - If the idea of creating an object until needed, cannot be applied here.
          - Theoretically is not possible, because when you pass a dependency to the class, you need to create it first. The passing itself is a usage of that dependency. 
          - Sometimes it is possible to do this with some kind of lazy generation, but in general not.
          - You should be very careful to the large data graphs.
      3. Numbs you from the pain
          - Too many dependencies might be created. 
          - Unit tests are easier.

Building an IoC Container
   What is: - It is just a framework to do the dependency injection. This is the basic.
                - Also it should configure dependencies (give me a concrete type instead of another one)
                - Automatically resolves the configured dependencies.
   So, when you ask for a particular object, it knows by interface or by type what concrete type is, and it goes down that chain and init that object with its references.
   Only IoC Container will know about those objects. The objects will never know about IoC Container. This is the key difference between an IoC Container and a Service Locator.
   In the following figure will be shown an example of IoC container in the shopper example:

   So, in other words, the shopper class requests a dependency which implements ICreditCard in constructor. There are 2 classes which are implementing ICreditCard: MasterCard and Visa. So, depending how IoC Container is configured, it will serve one of: MasterCard or Visa.

   
Using Unity
   Unity in an IoC container from Microsoft. It is part of Enterprise Library. Can be taken also as nuget package. And it is extendable. 

Setting up Unity
   You could do this via NuGet.

Registering types
    You need to create an unity container and register types (optional)
    - What is specific to Unity is that you don't need to register every dependency with Unity.
    - But if many classes implement an interface and we are asking for that interface, then we need to register, to let unity to give us what we need.
    - The basic scenario:
          var container = new UnityContainer();
       container.RegisterType<ICreditCard, MasterCard>();
   - If:
        - you want to register a type and when you will get it back you want to get it with a value:
             container.RegisterType<ICreditCard, MasterCard>( new InjectionProperty ("ChargeCount", 5));
        - you want to register a type with a name:
         container.RegisterType<ICreditCard, MasterCard> ("DefaultCard");
         container.RegisterType<ICreditCard, Visa>("BackupCard");
       - you want to register an Instance and get it back:
         var object = new object();
         container.RegisterInstance

Using container
    - In order to use, your usually command is Resolve:
             var shopper = container.Resolve<Shopper>();

Controlling lifetime of an object
    - With an IoC you could choose between having a singleton or an instance.
    - The default is to create an instance every time when the container resolves a request.
    - For a singleton: 
    container.RegisterType<ICreditCard, MasterCard>(new ContainerControlledLifeTime());