2010-11-14 53 views
3

我正在寫一個ASP.NET MVC網站,使用autofac進行依賴注入,Mindscape的Lightspeed作爲ORM。有一個UserRepository類,它依賴於一個燈光的UnitOfWork,並且它爲Logon控制器提供服務。爲什麼autofac在HttpRequest結束之前處理對象?

問題:前UserRepository被使用完的的UnitOfWork得到處理。

public class UserRepository : IUserRepository 
    { 
    private readonly BluechipModelUnitOfWork _unitOfWork; 

    public UserRepository(BluechipModelUnitOfWork unitOfWork) 
    { 
     _unitOfWork = unitOfWork; 
    } 
    public Principal GetPrincipal(string name) 
    { 
     // This line throws an ObjectDisposedException - UnitOfWork is already disposed. 
     return _unitOfWork.Principals.FirstOrDefault(p => p.Name == name); 
    } 
    ... 

在Global.asax中,如下依賴佈線完成:

public class MvcApplication : HttpApplication, IContainerProviderAccessor 
{ 
    private static void RegisterAutofac() 
    { 
     var builder = new ContainerBuilder(); 

     // Register the lightspeed context as a singleton 
     builder.RegisterInstance(new LightSpeedContext<BluechipModelUnitOfWork>("LightSpeedBluechip")) 
      .As<LightSpeedContext<BluechipModelUnitOfWork>>() 
      .SingleInstance(); 

     // Register the unit of work constructor so that a new instance is bound to each HttpRequest 
     builder.Register(c => c.Resolve<LightSpeedContext<BluechipModelUnitOfWork>>().CreateUnitOfWork()) 
      .As<BluechipModelUnitOfWork>() 
      .InstancePerLifetimeScope(); 

     // Register user repository to be one instance per HttpRequest lifetime 
     builder.Register(c => new UserRepository(c.Resolve<BluechipModelUnitOfWork>())) 
      .As<IUserRepository>() 
      .InstancePerLifetimeScope(); 

     builder.Register(c => new CurrentUserService(
            c.Resolve<HttpSessionState>(), 
            c.Resolve<IUserRepository>(), 
            c.Resolve<IMembershipService>()) 
      ).As<ICurrentUserService>() 
      .CacheInSession(); 

     builder.RegisterType<ExtensibleActionInvoker>().As<IActionInvoker>(); 
     builder.RegisterControllers(Assembly.GetExecutingAssembly()).PropertiesAutowired().InjectActionInvoker(); 
     builder.RegisterModelBinders(Assembly.GetExecutingAssembly()); 

     // Set the container provider up with registrations.  
     _containerProvider = new ContainerProvider(builder.Build()); 

     // Set the controller factory using the container provider.  
     ControllerBuilder.Current.SetControllerFactory(new AutofacControllerFactory(_containerProvider)); 

鑑於上述註冊,爲什麼會被autofac處置的的UnitOfWork(

回答

2

我能夠追查問題 - 這是一個愚蠢但微妙的陷阱... 我有一個CurrentUserService類,我註冊如下:

builder.Register(c => new CurrentUserService(
            c.Resolve<HttpSessionState>(), 
            c.Resolve<IUserRepository>(), 
            c.Resolve<IMembershipService>()) 
      ).As<ICurrentUserService>() 
      .CacheInSession(); 

問題是CacheInSession(),因爲CurrentUserService取決於IUserRepository,哪個autofac被忠實地注入,但隨後在第一個請求結束時丟棄。

這使成光的東西很明顯,但細微處注意連接最多依賴注射時:

確保高階家屬始終具有相同或使用壽命更短他們所依賴的服務。在我的情況下,溶液是改變上面的代碼:

 builder.Register(c => new CurrentUserService(
            c.Resolve<HttpSessionState>(), 
            c.Resolve<IUserRepository>(), 
            c.Resolve<IMembershipService>()) 
      ).As<ICurrentUserService>() 
      .InstancePerLifetimeScope(); 

....其防止CurrentUserService來自離活其所依賴的實例。

相關問題