【问题标题】:Ninject context extraction from factory parameter从工厂参数中提取上下文
【发布时间】:2014-03-29 04:07:42
【问题描述】:

我有一个定义范围的对象:

Bind<ISomething>().To<Something>().DefinesNamedScope(SomethingScope);

我还有一个创建 IAnotherThing 的自动生成工厂:

public interface IAnotherThingFactory
{
   IAnotherThing CreateAnotherThing(ISomething x);
}

并绑定它:

Bind<IAnotherThingFactory>().ToFactory();

我想在 ISomething 的上下文中创建 IAnotherThing,所以我可以例如有一个 ISharedPrivateDependency 两者都获得相同的实例。但是,Something 必须不知道 IAnotherThing。这意味着,理想情况下,应该有一种方法可以从 ISomething 参数中提取上下文,并使用它来设置 IAnotherThing 的上下文。

为了获得这种行为,我必须定义什么绑定或编写代码?

我不想直接暴露内核,只暴露工厂。

在 cmets 之后编辑:

  • 将 AnotherThing 的工厂放入 ISomething 可解决上下文问题,但会将 ISomething 暴露给 IAnotherThing。上面说明了对答案的要求:ISomething 一定不知道 IAnotherThing。所以这是不行的。
  • 在 ISomething 接口中公开 Ninject-internals 也是如此。

【问题讨论】:

  • 你能解释一下你所说的“上下文”是什么意思吗?您是否在问如何在ISomething 内部使用IAnotherThingISomething 不知道IAnotherThing? ....
  • Ninject Context Preservation Extension 意义上的上下文。
  • 您是否明确需要使用ToFactory() 或者创建自己的工厂/供应商是否可行?
  • 我更喜欢 ToFactory(),但这不是必需的。
  • Ninject 没有检索先前实例化对象的上下文的功能。因此,如果不修改 ninject,就无法满足您的要求。

标签: c# dependency-injection scope ninject


【解决方案1】:

看看 ninject contextpreservation 扩展:https://github.com/ninject/ninject.extensions.contextpreservation/wiki

ISomething 需要提供IAnotherThingFactory(例如作为属性),以便IAnotherThingFactory 创建的对象使用与ISomething 相同的上下文。

提示:工厂的范围可能是相关的。如果您定义工厂.InSingletonScope,它将不起作用,或者更确切地说,工厂创建的所有对象都将与第一次请求工厂的对象具有相同的上下文。

如果您需要它更通用,您可以将IResolutionRoot 注入ISomething 并将其作为属性提供。然后有人可以做ISomething.ResolutionRoot.GetContextPresreving&lt;IFoo&gt;(); 甚至 ISomething.ResolutionRoot.GetContextPresreving&lt;IAnotherThingFactory&gt;().CreateAnotherThing();

如果您不想引用 ninject,您可以将 IResolutionRoot 隐藏在包装器 IFactory 中,例如:

internal class Factory : IFactory {

    private readonly IResolutionRoot resolutionRoot;

    public Factory(IResolutionRoot resolutionRoot) {
        this.resolutionRoot = resolutionRoot;
    }

    T Create<T>() {
        return this.resolutionRoot.GetContextPreserving<T>();
    }
}

但是我建议这可以通过改进设计(在更大范围内)来解决。至少对我们来说,从来没有必要做这样的事情——即使我们需要在与另一个对象相同的上下文中后期创建对象,而创建是从不同的上下文触发的。

【讨论】:

  • 是的,这可以通过将工厂放到 ISomething 上来解决。但我明确不想这样做(这就是为什么我写 ISomething 一定不知道 IAnotherThing)。如果我公开了一个 resolutionroot,我会暴露 ninject,我也不想这样做。
  • 然后将IResolutionRoot包裹在另一个接口后面,比如IFactory.Create&lt;T&gt;()
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-20
  • 2011-10-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多