Scoping With Autofac IoC

2016/03/09

Scoping With Autofac IoC

This post continue the Microsoft.Composition (Portable MEF): Scoping

and it dealing with scoping on Autofac IoC.

Now days Autofac is my favorite IoC framework, It has reach API which is

relatively easy to use and it has great documentation.

It’s also very alive and It has version for .NET Core.

 

you can read about scoping with Unity IoC on this post.

If you didn’t read the Microsoft.Composition post it is recommend to take

a look at it before reading this post.

this post will focus on the API (and won’t discuss the concept). 

 

How Autofac is doing scoping?

Code Snippet
  1. var builder = new ContainerBuilder();
  2. builder.RegisterType<Global>()
  3.     .As<IGlobal>()
  4.     .SingleInstance();
  5. builder.RegisterType<Process>()
  6.     .As<IProcess>()
  7.     .SingleInstance();
  8. builder.Register(c => new Request(c.Resolve<ILifetimeScope>()))
  9.     .As<IRequest>()
  10.     .InstancePerLifetimeScope();
  11. builder.Register<IItemPerRequest>(c => new ItemPerRequest(c.Resolve<ILifetimeScope>()))
  12.     .InstancePerLifetimeScope();
  13.  
  14. using (var container = builder.Build())
  15. {
  16.     var process = container.Resolve<IProcess>();
  17.     process.Execute();
  18. }

Autofac register scope by the InstancePerLifetimeScope (fluent API).

 

Code Snippet
  1. public class Process : IProcess
  2. {
  3.     private IGlobal Global { get; }
  4.  
  5.     private ILifetimeScope _container;
  6.     public Process(ILifetimeScope container)
  7.     {
  8.         _container = container;
  9.         Global = container.Resolve<IGlobal>();
  10.     }
  11.  
  12.     public void Execute()
  13.     {
  14.         Console.WriteLine($"Global = {Global.Id}");
  15.  
  16.         using (var childContainer = _container.BeginLifetimeScope())
  17.         {
  18.             IRequest request = childContainer.Resolve<IRequest>();
  19.             request.Send();
  20.         }
  21.  
  22.         using (var childContainer = _container.BeginLifetimeScope())
  23.         {
  24.             IRequest request = childContainer.Resolve<IRequest>();
  25.             request.Send();
  26.         }
  27.     }
  28. }

Autofac create the scope context by calling BeginLifetimeScope.

Then you have to resolve the request using the child container.

 

Code Snippet
  1. public class Request : IRequest
  2. {
  3.     private static int _statId = 0;
  4.     public int Id { get; } = ++_statId;
  5.     public Request(ILifetimeScope container)
  6.     {
  7.         Global = container.Resolve<IGlobal>();
  8.         ItemPerRequestA = container.Resolve<IItemPerRequest>();
  9.         ItemPerRequestB = container.Resolve<IItemPerRequest>();
  10.     }
  11.  
  12.     public void Send()
  13.     {
  14.         Console.WriteLine($"\tRequest Id = {Id}");
  15.         Console.WriteLine($"\t\tGlobal = {Global.Id}");
  16.         Console.WriteLine($"\t\tItem A: {ItemPerRequestA}");
  17.         Console.WriteLine($"\t\tItem B: {ItemPerRequestB}");
  18.     }
  19.  
  20.     public IGlobal Global { get; set; }
  21.  
  22.     public IItemPerRequest ItemPerRequestA { get; set; }
  23.     public IItemPerRequest ItemPerRequestB { get; set; }
  24. }

The request resolve IGlobal which is singleton and IItemPerRequest which create under the scope.

 

Code Snippet
  1. public class ItemPerRequest : IItemPerRequest
  2. {
  3.     private ILifetimeScope _container;
  4.     public ItemPerRequest(ILifetimeScope container)
  5.     {
  6.         _container = container;
  7.     }
  8.  
  9.     private static int _statId = 100;
  10.     public int Id { get; } = _statId++;
  11.  
  12.     public override string ToString()
  13.     {
  14.         // Unity don't support mutual dependency via attribute model
  15.         var request = _container.Resolve<IRequest>();
  16.         return $"Id = {Id} — of request –> {request.Id}";
  17.     }
  18. }

The ItemPerRequest must use lazy resolve (line 15) in order of resolving mutual dependency.

Autofac don’t have attribute model and construction injection cannot handle mutual dependency by definition.

 

The output of the execution should look like:

DI, IoC, Autofac, Unity, MEF, Composition, Import, dependency, Injection

 

Summary

Autofac is my favorite IoC now days, it is having lots of functionality and fairly clear API.

on latter post I will suggest async pattern to solve the mutual dependency issue.

Add comment
facebook linkedin twitter email

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*