6

我想知道如何使用 DI 管理对象。假设我有一堂课

class Foo : IFoo, IDisposable
{
    // ...
}

然后这个类被注入到另一个类中

class Bar
{
    public Bar(IFoo foo)
    {
        this.Foo = foo
    }

    IFoo Foo { get; set; }
 }

然后我在某个范围内绑定它(我的示例使用 MVC 和 Ninject)

this.Bind<IFoo>().To<Foo>().InRequestScope();

我想知道,既然依赖注入框架处理 的生命周期Foo,我应该在 中实现 IDispoableBar吗?我的想法是 DI 正在管理 的生命周期Foo,所以不要碰它,以防另一个类正在使用Foo. Bar另外,由于一次性对象是作为构造函数参数传入的,Bar不会包装一次性对象,所以它不知道调用者Bar想要使用Foo的对象是如何Bar被垃圾回收的。这是正确的吗?

4

2 回答 2

3

是的,你的假设是正确的。Ninject 将为您处理该对象。

于 2012-12-07T09:04:13.063 回答
3

这是管理生命周期的一般问题。基本规则是创建对象的人拥有该实例的所有权。所有者应处置/销毁该实例。所有权可以传递给其他人,这使得“其他人”负责销毁该实例。

在您的情况下,Foo 实例不是由 Bar 创建的,因此 bar 不负责处理该实例。由于 Ninject 为您创建了该实例,因此它负责对其进行清理。

所有权可以传递,但这必须是明确的。显式所有权传递的一个很好的例子是工厂设计模式:

IFoo CreateNewFoo();

尽管此方法创建了新IFoo实例,但很明显他将所有权传回给调用者。

传递所有权的坏方法的一个很好的例子是 .NET 的StreamReader类。它在其构造函数中接受一个一次性对象,但它拥有所有权。尽管文档声明该类处理给定对象,但这种行为让许多开发人员感到眼花缭乱,因为它违反了所有权的一般规则。微软最终在 .NET 4.5 中通过添加允许抑制给定流的处置的 ctor 重载来解决此问题。

于 2012-12-10T14:54:17.453 回答