title: Autofac Lifetime Management
body: <p>I'm working on an ASP.NET MVC project that support external plugins, now, I'm moving from Unity to Autofac and I need to wrap the lifetime objects of Autofac so the plugins won't have to reference it, in Unity I could do something this.</p>
  
  <pre><code>public sealed class UnityScopeFactory : IDependencyScopeFactory
  {
      private HttpRequestScope _httpRequest;
  
      private SingletonScope _singleton;
  
      private TransientScope _transient;
  
      public IDependencyScope HttpRequest()
      {
          return _httpRequest ?? (_httpRequest = new HttpRequestScope());
      }
  
      public IDependencyScope Singleton()
      {
          return _singleton ?? (_singleton = new SingletonScope());
      }
  
      public IDependencyScope Transient()
      {
          return _transient ?? (_transient = new TransientScope());
      }
  
      private class HttpRequestScope : IDependencyScope
      {
          public object CreateScope()
          {
              return new HttpPerRequestLifetimeManager();
          }
      }
  
      private class SingletonScope : IDependencyScope
      {
          public object CreateScope()
          {
              return new ContainerControlledLifetimeManager();
          }
      }
  
      private class TransientScope : IDependencyScope
      {
          public object CreateScope()
          {
              return new TransientLifetimeManager();
          }
      }
  }
  </code></pre>
  
  <p>I made similar thing in Autofac but I'm not sure whether it's the correct way to do that, I looked into the RegistrationBuilder of Autofac which is (unfortunately) internal and I came up with this. </p>
  
  <pre><code>public class AutofacScopeFactory : IDependencyScopeFactory
  {
      private HttpRequestScope _httpRequest;
  
      private SingletonScope _singleton;
  
      private TransientScope _transient;
  
      public IDependencyScope HttpRequest()
      {
          return _httpRequest ?? (_httpRequest = new HttpRequestScope());
      }
  
      public IDependencyScope Singleton()
      {
          return _singleton ?? (_singleton = new SingletonScope());
      }
  
      public IDependencyScope Transient()
      {
          return _transient ?? (_transient = new TransientScope());
      }
  
      private class HttpRequestScope : IDependencyScope
      {
          public object CreateScope()
          {
              return new CurrentScopeLifetime();
          }
      }
  
      private class SingletonScope : IDependencyScope
      {
          public object CreateScope()
          {
              return new RootScopeLifetime();
          }
      }
  
      private class TransientScope : IDependencyScope
      {
          public object CreateScope()
          {
              return new CurrentScopeLifetime();
          }
      }
  }
  </code></pre>
  
  <p>Also, after I got this to work, how can I use pass it to the ContainerBuilder?</p>
  
  <p>In Unity I could do something like this.</p>
  
  <pre><code>public sealed class UnityDependencyContainer : IDependencyContainer
  {
      private readonly IUnityContainer _container;
  
      public UnityDependencyContainer()
      {
          _container = new UnityContainer()
      }
  
      public void Register&lt;TContract, TImplementation&gt;(IDependencyScope scope) where TImplementation : TContract
      {
          LifetimeManager manager = scope.CreateScope() as LifetimeManager;
  
          if (manager != null)
          {
              _container.RegisterType&lt;TContract, TImplementation&gt;(manager);
          }
      }
  }
  </code></pre>
  
  <p>How do I pass an instance of IComponentLifetime to the method chain? is it a dead end?</p>
  
  <pre><code>public class AutofacContainer : IDependencyContainer
  {
      private static readonly ContainerBuilder Builder;
  
      static AutofacContainer()
      {
          Builder = new ContainerBuilder();
      }
  
      public void RegisterType&lt;TContract, TImplementation&gt;(IDependencyScope scope) where TImplementation : TContract
      {
          IComponentLifetime manager = scope.CreateScope() as IComponentLifetime;
  
          if (manager != null)
          {
              Builder.RegisterType&lt;TImplementation&gt;().As&lt;TContract&gt;();
          }
      }
  }
  </code></pre>