我有一个问题,我要签这个 主观的 因为我是这么认为它演变成,更多的讨论。我希望对于一些很好的想法或作一些思考-provokers.很抱歉我长篇大论的问题,但你需要知道的上下文。

这个问题基本上是:

  • 你怎么处理具体类型的关系IoC容器?具体而言,谁是负责处理它们,如果它们需要处置,以及如何,知识得到传播出去呼叫密码?

你要求他们IDisposable?如果没有,是这一代面向未来,或者是规则,不能使用一次性对象?如果强制执行IDisposable-要求在接和具体类型的未来-的证据,其责任是对象注作为一部分的构造的电话?


编辑:我接受的答案 @克里斯*巴拉德 由于这是最近的一个方法我们结束了。

基本上,我们总是返回的一种类型,看起来是这样的:

public interface IService<T> : IDisposable
    where T: class
{
    T Instance { get; }
    Boolean Success { get; }
    String FailureMessage { get; } // in case Success=false
}

我们然后返回一个对象执行这一口回。解决。TryResolve,使我们得到的调用代码的总是相同的类型。

现在,对象执行这一接口, IService<T> 是IDisposable,并应 总是 以处置。这不是到编程员可以解决一个服务来决定是否 IService<T> 对象应该被设置或没有。

然而,这是至关重要的一部分,该业务是否实例应当设置或没有,这些知识融入的目的落实 IService<T>, 所以如果它是一家工厂范围内的服务(ie。每个调决心结束了与新的服务实例),则服务实例将设置时 IService<T> 目的是设置的。

这也使得它能够支持其他特殊的范围,像池。我们现在可以说,我们想要至少2服务的实例、最大值15,并且通常5,这意味着每次呼叫。解决,无论检索服务实例,从一个游泳池的提供对象,或者建造一个新的一个。然后,当时的 IService<T> 目的,持有该汇集的服务设置的,服务的实例被释放回到游泳池。

当然,这使所有的代码这样的:

using (var service = ServiceContainer.Global.Resolve<ISomeService>())
{
    service.Instance.DoSomething();
}

但这是一个干净的做法,和它具有相同的语法的类型无关的业务或具体目中使用,所以我们选择了这样一个可接受的解决方案。


原来的问题如下,为子孙后代


冗长的问题来了这里:

我们有一个IoC容器,我们使用,并且最近我们发现了什么数额的问题。

在非IoC代码,当我们想到使用,也就是说,一个文件,我们使用的一类是这样的:

using (Stream stream = new FileStream(...))
{
    ...
}

毫无疑问,是否有此类的东西,保持一个资源有限或者没有,因为我们知道,文件必须关闭,以及类本身实施IDisposable.规则很简单,就是每一类中,我们建造一个目的,即实现IDisposable,有待处置。没有问题要问。它没有达到用户的这类决定,如果调处理是可选择或没有。

好吧,那么上来的第一步,国际奥委会的容器中。让我们假设,我们不想代码直接对话的文件,但不是通过一个间接层.让我们叫这类BinaryDataProvider为这个例子。在国内,这类使用流,这仍然是一个一次性的目的,所以上述码将改为:

using (BinaryDataProvider provider = new BinaryDataProvider(...))
{
    ...
}

这没有太大变化。知识这类实现IDisposable还在这里,没有任何问题,我们需要呼吁处置。

但是,让我们假设,我们有课程,提供数据,现在不使用任何这样的有限的资源。

上述代码然后可以写为:

BinaryDataProvider provider = new BinaryDataProvider();
...

OK,so far so good,但是来这里的肉类的问题。让我们假设,我们想到使用IoC容器中注入这个供应商,而不是取决于一个特定的具体类型。

代码,然后将:

IBinaryDataProvider provider =
    ServiceContainer.Global.Resolve<IBinaryDataProvider>();
...

注意,我假定存在独立接口可用,我们可以访问的目的通过。

与上述变化,如果我们晚上要用的对象真的应该加以处置?没有任何现有代码,可解决该接口是书面处置的对象,现在怎么样?

我们看到它,我们必须挑选一个解决办法:

  • 执行运行检查,检查,如果一个具体的类型正在注册实现IDisposable,要求该接口,它是通过暴露也实现了IDisposable.这不是一个很好的解决方案
  • Enfore约束的接口正在使用的,他们必须总是继承自IDisposable,以便能向未来
  • 强制执行运行时,没有具体类型可IDisposable,由于这是具体处理不通过代码使用国际奥委会的容器
  • 只是把它留给程序检查,如果对象实现IDisposable和"做正确的事"?
  • 有没有其他人吗?

此外,什么有关注射对象在构造?我们的容器,而其他一些集装箱我们已经看到的,是能够注入新鲜的对象为一个参数的一个构造的一个具体的类型。例如,如果我们的 BinaryDataProvider 需要一个对象,实现了 ILogging 接口,如果我们执行IDispose-"能力"在这些对象,其责任是处置的记录象?

你怎么想?我想观点、良好的和坏的。

有帮助吗?

解决方案

(免责声明:我回答这个基础上java的东西。虽然我的程序C#我有没有代理的任何C#但我知道这是可能的。抱歉java术语)

你可以让国际奥委会框架内进行检查的对象正在建造,看它是否支持 IDisposable.如果不是,你可以使用一个动态代理包裹的实际目的,国际奥委会框架提供给客户的代码。这一动态代理可能实现IDisposable,这样,你总是提供一个IDisposable给客户。只要你使用的接口,这应该是相当简单吗?

然后你就有问题的通信的开发 对象是一个IDisposable.我真的不知道这怎么会做一个好的方式。

其他提示

一个选择可能是去工厂案,以便创建的对象直接通过国际奥委会的容器不需要设置自己,例如:

IBinaryDataProviderFactory factory =
    ServiceContainer.Global.Resolve<IBinaryDataProviderFactory>();
using(IBinaryDataProvider provider = factory.CreateProvider())
{
    ...
}

缺点是增加的复杂性,但这并不意味着容器永远不会造成任何开发商是应该处置的-这是总是明确的代码这样做。

如果你真的想让它显而易见,该工厂的方法可以命名为类似CreateDisposableProvider().

你实际上想出了一个非常肮脏的解决方案:你的 IService 合同违反了 SRP, ,这是一个很大的不-没有。

我的建议是以区别所谓的"单独"的服务,从所谓的"原型"服务。寿命的"单独"的管理的容器,这可以查询在运行时是否一个特别实例,实现了 IDisposable 和调用 Dispose() 在关闭如果是这样。

管理原型,另一方面,是完全的责任的呼叫代码。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top