Tuesday, 20 January 2015

Autofac

Basic Setup

Autofac is a nifty dependency injection container that comes as a PCL (Portable Class Library) so it can be used in Xamarin projects.

To set it up you need to build a container using the ContainerBuilder class:
 var containerBuilder = new ContainerBuilder();  
   
 containerBuilder.RegisterSource(new AnyConcreteTypeNotAlreadyRegisteredSource());  
 
 // Register Types
   
 _container = containerBuilder.Build();  
You can then register types like this:
 container.RegisterType<First>().As<IFirst>();   
To use the container to resolve objects you need to get a lifetime scope from it:
 using (var scope = _container.BeginLifetimeScope())  
 {  
   // Reslove Types  
 }  
You can then resolve types like so:
 var first = scope.Resolve<IFirst>();  
If you are using MVC/Web.Api you can add additional nuget packages that will enable constructor injection on your controllers!


Automatic resolution of concrete types

If you want the container to automatically resolve concrete types you can add this to the container builder. This will mean that if it can't find a registration and the type is a concrete (non-interface, non-abstract) class it will just new up the class and return it.
 containerBuilder.RegisterSource(new AnyConcreteTypeNotAlreadyRegisteredSource());  


Passing some parameters

You can pass in some parameters and the container will automatically resolve the non passed ones. This means you can have a constructor like this and still pass in some of the parameters and have the container resolve the others automatically.
 public Test(IFirst first, ISecond second)  
To pass in the IFirst parameter just do:
 var test = scope.Resolve<Test>(new TypedParameter(typeof(IFirst), first));  
This will then pass first in and create a new Second instance. 


delegate Factories

You can use a Func<T> as a factory, this will then pass in a function that will resolve instances from the container so you can create multiple instances.
     public NeedAFactory(Func<Test> factory)  
     {  
       _test1 = factory();  
       _test2 = factory();  
     }  


Delegate Factories with parameters

You can also add a Func that takes parameters and this will be passed in to the constructor of the class when it is constructed.
   internal class Parent  
   {  
     private IChild _child;  
   
     public Parent(Func<Parent, IChild> factory)  
     {  
       _child = factory(this);  
     }  
   }  
   
   internal class Child : IChild  
   {  
     private readonly Parent _parent;  
   
     public Child(Parent parent)  
     {  
       _parent = parent;  
     }  
   }  
When autofac creates the child class it will pass the varable specified in the parent (this).

No comments:

Post a Comment