Unity和TransientLifetimeManager

7

这是一个小问题,只是为了确保我正确理解Unity。

我正在一个ASP.NET MVC应用程序中使用Unity,并已经如下注册了类型:

 container.RegisterType<IPizzaService, PizzaService>(); 

我正在控制器中使用它,类似于:

public class PizzaController : Controller
{
    private IPizzaService _pizzaService;

    public PizzaController(IPizzaService pizzaService)
    {
        _pizzaService = pizzaService;
    }

    [HttpGet]
    public ActionResult Index()
    {
        var pizzasModel = _pizzaService.FindAllPizzas();
        ...        
    }        
}

每次发出页面请求时,都会注入并使用 IPizzaService 的新实例。因此这一切都可以正常工作。
我的问题是:我需要做什么特殊的事情来处理这个实例?我认为,一旦请求结束,控制器就会被销毁并且 PizzaService 实例最终会被垃圾收集。
如果我需要确定性地处理一个实例,因为它使用了实体框架上下文或未受管理的资源,例如,我必须重写控制器的 Dispose 方法,并确保自己调用实例的 dispose。
对吧?如果不是,请解释一下为什么 :)
谢谢!

这里有很多信息(http://msdn.microsoft.com/en-us/library/ff660872%28v=pandp.20%29.aspx),但我认为短暂管理器不需要您自己处理它。 - Jeroen Vannevel
1
@JeroenVannevel 实际上,“TransientManager”不会为您调用“dispose”。 - Keith Payne
2个回答

1
在我看来,无论什么东西创建了一次性对象都应该负责处理它。当容器通过RegisterType<I, T>()注入一次性对象时,我希望确保该对象已准备好使用。但是,使用RegisterInstance<I>(obj)会自动清除您的对象。

这对于IOC容器来说可能很困难,而在Unity中则不可能。然而,有一些非常棒的代码可以解决这个问题,我一直在使用:

http://thorarin.net/blog/post/2013/02/12/Unity-IoC-lifetime-management-IDisposable-part1.aspx

博客中有一个DisposingTransientLifetimeManager和DisposingSharedLifetimeManager的代码。使用这些扩展,容器会在您的可处理对象上调用Dispose()
需要注意的是,您需要引用正确(较旧的)版本的Microsoft.Practices.Unity.Configuration.dll和Microsoft.Practices.Unity.dll。

谢谢,但在我描述的特定情况下,是否需要显式处理 dispose 或者垃圾回收器最终会自动处理? - L-Four
垃圾回收器最终会处理掉所有的资源,但这可能需要很长时间。垃圾回收是在进程内进行管理的。在IIS中,一个进程等同于一个应用程序池,但可能有多个.NET应用程序域(网站可以共享同一个应用程序池)。因此,一个垃圾回收器可能被多个Web请求共享。因此,您应该尽早释放资源,而不是等待垃圾回收器来处理。 - Keith Payne
那就意味着展示Unity和TransientLifetimeManager的所有示例都是错误的吗?那么,在什么情况下使用TransientLifetimeManager呢? - L-Four
如果您正在使用RegisterType<I,T>(),那么Unity将不会调用Unity创建的对象上的Dispose()方法。您可能正在查看使用RegisterInstance<T>(obj)的示例。在这种情况下,TransientLifetimeManager将像单例一样处理您的对象,并为您处理其释放。我将使答案措辞更加精确。谢谢。 - Keith Payne

0

ContainerControlledTransientManager 是于2018年1月11日在 Unity 中添加的。

添加容器“owned”短暂生命周期管理器ContainerControlledTransientManager #37

因此,需要使用 ContainerControlledTransientManager。这个生命周期管理器与 TransientLifetimeManager 相同,除非该对象实现了 IDisposable 接口,否则它将保持对该对象的强引用,并在容器被释放时将其释放。 如果创建的对象不是可释放的,则容器不会维护任何对象引用,因此当该对象被释放时,GC将立即收集它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接