从工厂参数中提取Ninject上下文

时间:2014-02-26 11:11:41

标签: c# dependency-injection scope ninject

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

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

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

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

绑定它:

Bind<IAnotherThingFactory>().ToFactory();

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

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

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

评论后编辑:

  • 将Factory for AnotherThing放入ISomething可以解决上下文问题,但会将ISomething暴露给IAnotherThing。答案的要求如上所述:ISomething一定不能知道IAnotherThing。所以这是不行的。
  • 在ISomething界面中暴露Ninject-internals同样如此。

1 个答案:

答案 0 :(得分:0)

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

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

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

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

如果您不想引用ninject,可以在包装IFactory中隐藏internal class Factory : IFactory { private readonly IResolutionRoot resolutionRoot; public Factory(IResolutionRoot resolutionRoot) { this.resolutionRoot = resolutionRoot; } T Create<T>() { return this.resolutionRoot.GetContextPreserving<T>(); } } ,例如:

{{1}}

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