Bre*_*ias 9 idisposable ioc-container
我建议在使用IOC容器时,我应该改变这个:
class Foobar: IFoobar, IDisposable {};
Run Code Online (Sandbox Code Playgroud)
进入:
interface IFoobar: IDisposable{};
class Foobar : IFoobar{};
Run Code Online (Sandbox Code Playgroud)
我想知道这是否正常,或者它是否解决了一个问题并创造了另一个问题.它肯定解决了我非常想要这样做的问题:
using( IFoobar = myContainer.Resolve<IFoobar>() )
{ ... }
Run Code Online (Sandbox Code Playgroud)
现在我知道任何替代品都不会导致运行时错误.
另一方面,现在我的所有模拟对象也必须处理IDisposable.我是对的,大多数任何模拟框架都能轻松处理这个问题吗?如果是,那么也许这不是问题.
或者是吗?我应该注意另一个隐藏的问题吗?这当然发生,我认为如果我使用IoC容器没有单元测试/嘲讽,但对于真正的服务的独立性,那么这可能是因为也许只有我的交换服务,一个真正与非托管资源交易(和现在我是一个问题我必须在这些其他服务中实现空的"IDispose"操作).
即使是后一个问题,我想我可以忍受,为了获得使用上面演示的"使用"声明的能力.但是,我是遵循一个流行的惯例,还是我错过了一个完全不同的更好的解决方案?
Mar*_*ann 11
从IDisposable中获取界面在我看来是一种设计气味,表明漏出抽象.正如Nicholas Blumhardt 所说:
接口通常不应该是一次性的.定义接口的人无法预见它的所有可能实现 - 您总是可以提出几乎任何接口的一次性实现.
考虑为什么要将IDisposable添加到您的界面.这可能是因为您有一个特定的实现.因此,实现泄漏到抽象中.
一个值得盐的DI容器应该知道它何时创建一次性类型的实例.当您随后要求容器释放对象图时,它应该自动处理一次性部件(如果他们的时间根据他们的生活方式而上升).
我知道至少Castle Windsor和Autofac会这样做.
所以在你的情况下,你应该像这样保持你的类型:
class Foobar: IFoobar, IDisposable {};
Run Code Online (Sandbox Code Playgroud)
您可能会发现Nicholas Blumhardt的帖子The Relationship Zoo也很有趣 - 特别是有关的讨论Owned<T>.