IOC容器和IDisposable [英] IOC containers and IDisposable

查看:93
本文介绍了IOC容器和IDisposable的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

向我建议,在使用IOC容器时,我应该对此进行更改:

It was recommended to me that, when using an IOC container, I should change this:

class Foobar: IFoobar, IDisposable {};

对此:

interface IFoobar: IDisposable{};
class Foobar : IFoobar{};

我想知道这是否可以,还是可以解决一个问题并创建另一个问题.它肯定解决了我非常想这样做的问题:

I'm wondering if this is ok, or if it solves one problem and creates another. It certainly solves the problem where I badly want to do this:

using( IFoobar = myContainer.Resolve<IFoobar>() )
{ ... }

现在我知道任何替代方法都不会导致运行时错误.

And now I know that any substitute won't cause a run-time error.

另一方面,现在我所有的模拟对象也必须处理IDisposable.我说大多数模拟框架都可以轻松处理吗?如果是,那么这可能不是问题.

On the other hand, now all my mock objects must handle IDisposable too. Am I right that most any mocking framework handles this easily? If yes, then perhaps this is a non-issue.

是吗?我应该注意另一个隐藏的陷阱吗?我当然想到,如果我不是将IOC容器用于单元测试/模拟,而是为了真正的服务独立性,那么这可能是一个问题,因为也许只有我的可交换服务中的一个实际上处理了非托管资源(现在我m必须在其他服务中实现空的"IDispose"操作.

Or is it? Is there another hidden gotcha I should watch for? It certainly occurs to me that if I were using an IOC container not for unit tests / mocking, but for true service independence, then this might be a problem because perhaps only one of my swappable services actually deals with unmanaged resources (and now I'm having to implement empty "IDispose" operations in these other services).

即使我想接受后一个问题,也可以像上面演示的那样获得使用使用"语句的能力.但是我是遵循流行的约定,还是错过了一个完全不同且更好的解决方案?

Even this latter issue I suppose I could live with, for the sake of gaining the ability to employ the "using" statement as I demoed above. But am I following a popular convention, or am I missing an entirely different and better solution?

推荐答案

从IDisposable派生接口是一种设计气味,它表示泄漏抽象.当尼古拉斯·布鲁姆哈特(Nicholas Blumhardt)放入:

Deriving an interface from IDisposable is in my opinion a design smell that indicates a Leaky Abstraction. As Nicholas Blumhardt put it:

界面通常不应是一次性的.daccess-ods.un.org daccess-ods.un.org没有一种方法可以定义一个接口来预见该接口的所有可能实现-您始终可以提出几乎任何接口的一次性实现.

an interface [...] generally shouldn't be disposable. There's no way for the one defining an interface to foresee all possible implementations of it - you can always come up with a disposable implementation of practically any interface.

考虑为什么要向界面添加IDisposable.可能是因为您有一个特定的实现.因此,实现会泄漏到抽象中.

Consider why you want to add IDisposable to your interface. It's probably because you have a particular implementation in mind. Hence, the implementation leaks into the abstraction.

值得创建盐的DI容器在创建一次性类型的实例时应该知道.随后,当您要求容器释放对象图时,容器应自动处置(如果它们的时间根据其生活方式而定).

An DI Container worth its salt should know when it creates an instance of a disposable type. When you subsequently ask the container to release an object graph, it should automatically dispose the disposable components (if their time is up according to their lifestyles).

我知道至少温莎城堡和Autofac会做到这一点.

I know that at least Castle Windsor and Autofac does this.

因此,在您的情况下,应保持这样的类型:

So in your case, you should keep your type like this:

class Foobar: IFoobar, IDisposable {};

您可能会发现Nicholas Blumhardt的帖子关系动物园也很有趣-尤其是有关Owned<T>的讨论.

You may find Nicholas Blumhardt's post The Relationship Zoo interesting as well - particularly the discussion about Owned<T>.

这篇关于IOC容器和IDisposable的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆