ASP.Net MVC 3 Unity IoC Disposal

时间:2012-07-26 15:27:05

标签: c# asp.net-mvc-3 dependency-injection inversion-of-control unity-container

我正在开发一个ASP.Net MVC 3 Web应用程序,它使用Unity 2.0作为IoC容器。

下面显示了 Global.asax 文件中 Application_Start()方法的示例

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();

    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);
    IUnityContainer container = new UnityContainer();

    container.RegisterType<IControllerActivator, CustomControllerActivator>(
        new HttpContextLifetimeManager<IControllerActivator>());

    //container.RegisterType<IUnitOfWork, UnitOfWork>(
    //  new ContainerControlledLifetimeManager());
    container.RegisterType<IUnitOfWork, UnitOfWork>(
        new HttpContextLifetimeManager<IUnitOfWork>());

    container.RegisterType<IListService, ListService>(
        new HttpContextLifetimeManager<IListService>());
    container.RegisterType<IShiftService, ShiftService>(
        new HttpContextLifetimeManager<IShiftService>());

    DependencyResolver.SetResolver(new UnityDependencyResolver(container));
}

我的 HttpContextLifetimeManager 看起来像这样

public class HttpContextLifetimeManager<T> : LifetimeManager, IDisposable
{
    public override object GetValue()
    {
        return HttpContext.Current.Items[typeof(T).AssemblyQualifiedName];
    }

    public override void RemoveValue()
    {
        HttpContext.Current.Items.Remove(typeof(T).AssemblyQualifiedName);
    }

    public override void SetValue(object newValue)
    {
        HttpContext.Current.Items[typeof(T).AssemblyQualifiedName] =
            newValue;
    }

    public void Dispose()
    {
        RemoveValue();
    }
}

我的问题是,当我在其上放置断点时,从不调用上述类中的方法 Dispose()。我担心我的IoC容器实例永远不会被丢弃。这会导致问题吗?

我在 Global.asax 文件中找到了这段代码,但仍然没有调用 Dispose()方法

protected void Application_EndRequest(object sender, EventArgs e)
{
    using (DependencyResolver.Current as IDisposable);
}

任何人都可以帮我解决如何处理Unity容器的每个实例吗?

感谢。

2 个答案:

答案 0 :(得分:3)

使用Unity.MVC3 nuget包。然后在初始化时指定HierarchicalLifetimeManager,并在每次请求后处理您的对象。

container.RegisterType(new HierarchicalLifetimeManager());

就这么简单:)

答案 1 :(得分:2)

Unity不会跟踪它创建的实例,也不会处理它们。 Rory Primrose有一个extension that does the tracking,可以通过调用container.TearDown()来处理对象。

LifetimeManagers自行清理wishlist for Unity vNext

如果您在每个请求中执行此操作,则引导新容器实例的代价很高。因此,在完成所有注册后,我会考虑缓存容器实例。