2017-09-26 98 views
0

我有以下结构。我很困惑的是如何处置PhoneBase。我不知道Unity是否处置了PhoneBase在Unity中处理基类的最佳做法是什么

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(); 
    } 
} 
+0

“我不知道Unity是否配置了PhoneBase。”你有没有试图看看会发生什么? – Steven

+0

Unity与处置无关。它是在请求结束时处理控制器实例的MVC管道。这意味着第二个版本是正确的,ASP.NET管道在你的控制器上调用Dispose,并在你的自定义对象上调用Dispose。 –

回答

2

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

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

然后,如果你在的地方IMyPhone注入MyPhone,团结是拥有该对象的实体,因此是一个负责的处置它(它会做,在其生命周期结束,如在您的DI配置中定义)。您的控制器应该绝对不是处置它。期。控制器不拥有它,如果Unity在其他任何地方注入它,则会在其他实例中发生异常,因为该对象已被错误地处置。

作为一个方面说明,如果不恰当地实现和使用IDisposable要比不处理应该是的对象更糟糕。最终,GC将处理任何遗留问题。手动处理只是一个好的家务。但是,处置不当可能会导致内存泄漏,抛出异常,并在应用程序中造成各种不便。因此,标准建议是,如果您知道自己在做什么以及您为什么这样做,则只应实施IDisposable。如果您不确定,请不要实施。

+0

感谢您的解释.. – derodevil

相关问题