Search code examples
inversion-of-controlautofac

With Autofac what would be the advantages and disadvantages


I've read about Autofac that it's fast. I've seen the coding involved and it's pretty neat. But I'm not quite sure how to use it. I've used StructureMap, and it has a static ObjectFactory. Ninject has the Kernel, but in Autofac's Google pages they recommend doing something like this :

using( var resolver = builder.Build() ){
   var whatINeed = resolver.Resolve<INeedThisService>();
}

It's a WinForms app, so I got an Invalid Object state from doing the above, so I switched to having a global IContainer, and did it this way

 using( var resolver = Program.Container.CreateInnerContainer() )
 {
     var whatINeed = resolver.Resolve<INeedThisService>();
 }

I've used it about 3 or 5 times. But is that efficient? Or should I just do something like

 var whatINeed = Program.Resolve<INeedThisService>()

and under the covers

 internal static TServervice Resolver<TService>(){
       if(_container == null ) _container = builder.Build();
       return _container.Resolve<TService>();
 }

Which would you use, and why? Also is there a penalty for working with CreateInnerContainer()?


Solution

  • I am not an AutoFac expert but do have experience with other Ioc containers. I thought this question would give me a reason to try AutoFac.

    Designs based on Ioc containers should strive to isolate all code from having access to the container except at the entry point or host level. I created the following example using AutoFac and WinForms to show how a form could access a service via it's constructor.

    I'm not quite sure why you thought you needed the inner container. Perhaps you could comment and I can provide a more detailed response.

    static class Program
    {
        [STAThread]
        static void Main()
        {
            var builder = new ContainerBuilder();
            builder.Register<TheService>().As<INeedThisService>();
            builder.Register(f => new Form1(f.Resolve<INeedThisService>())).As<Form1>();
    
            using (var container = builder.Build())
            {
                Application.Run(container.Resolve<Form1>());
            }
    
        }
    }
    
    public interface INeedThisService { }
    
    public class TheService : INeedThisService
    {
        public TheService() { Console.WriteLine("ctor ThisService"); }
    }
    
    public partial class Form1 : Form
    {
        public Form1(INeedThisService service)
        {
            Console.WriteLine("ctor Form1");
            InitializeComponent();
        }
    }