在Unity中部署基类的最佳实践是什么?

时间:2017-09-26 13:47:21

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

我有以下结构。令我困惑的是如何处置PhoneBase。我不知道Unity是否处理PhoneBase

public class PhoneBase : IDisposable
{
    protected int GetSignal()
    {
    }

    //something needs to dispose
    public void Dispose()
    {
    }
}

public interface IMyPhone
{
    void SwitchOn();
    void SwitchOff();
}

public class MyPhone : PhoneBase, IMyPhone
{
    public void SwitchOn()
    {
        //implement
    }

    public void SwitchOff()
    {
        //implement
    }

}

public class PhoneQuestionController : Controller
{
    IMyPhone myPhone;
    public PhoneQuestionController(IMyPhone myPhone)
    {
        this.myPhone = myPhone;
    }
}

我应该将Dispose方法放在IMyPhone界面中,然后在覆盖Dispose控制器的同时调用它,如下所示?或者有更好的方法吗?

public interface IMyPhone
{
    void SwitchOn();
    void SwitchOff();
    void Dispose();
}

public class PhoneQuestionController : Controller
{
    IMyPhone myPhone;
    public PhoneQuestionController(IMyPhone myPhone)
    {
        this.myPhone = myPhone;
    }

    override Dispose(bool disposing)
    {
        base.Dispose(disposing);
        myPhone.Dispose();
    }
}

1 个答案:

答案 0 :(得分:2)

我不认为你理解IDisposable的目的。如果一个类拥有本身是一次性的资源,那么它应该只实现IDisposable。这意味着该类必须实际上新的东西, not 被注入。一个班级不应该处理注入的资源;这就是对象生命周期管理器的工作 - 在这种情况下是Unity。

假设PhoneBase确实拥有一些可支配资源,那么MyPhone将继承此资源和IDisposable实现。实际上,PhoneBase在这种情况下实际上并不存在。它不像MyPhone以某种方式对PhoneBase实例有内部引用。您所拥有的只是一个MyPhone实例,具有与PhoneBase相同的所有属性和方法,以及在其上专门定义的任何内容。

然后,如果您重新注入MyPhone代替IMyPhone,Unity就是拥有该对象的实体,因此负责处理该对象(它将执行此操作) ,在其生命周期结束时,如您的DI配置中所定义)。您的控制器绝对不会处理它。期。控制器不拥有它,如果Unity在其他任何地方注入它,那么您将在其他实例中获得异常,因为该对象已被错误地处理。

作为旁注,不正确地实施和使用IDisposable要比不处理你应该使用的对象要糟糕得多。最终,GC将负责任何遗留下来的事情。手动处理只是好管家。但是,不正确的处理可能会导致内存泄漏,抛出异常,并在应用程序上造成各种各样的肮脏。因此,标准建议是,如果您知道自己正在做什么以及确切地知道自己为何会这样做,那么您应该只实施IDisposable。如果您不确定,请不要实施它。