在Ninject中将单例绑定到多个服务

Mic*_*icz 9 .net ninject inversion-of-control ninject-2

我有一个问题,似乎与http://markmail.org/message/6rlrzkgyx3pspmnf中描述的问题非常相似,如果您使用不同的服务类型访问它,实际上创建的单个实例不仅仅是单个实例.

我正在使用最新版本的Ninject 2 for Compact Framework,我遇到的确切问题是,如果我将相同的提供程序方法绑定到:

Func<Service> serviceCreator = () => new Service(false);
kernel.Bind<IService>().ToMethod(serviceCreator).InSingletonScope();
kernel.Bind<Service>().ToMethod(serviceCreator).InSingletonScope();
Run Code Online (Sandbox Code Playgroud)

如果我将它们解析为IService和Service,它似乎创建了2个Service实例.

这在解析Service时会导致循环依赖性异常.

这是设计,还是一个bug?

Rub*_*ink 11

在V3中,最终有一个新的重载Bind形式的解决方案,请参阅以下相关:问题.


如果您希望共享单例,则需要将第二个更改Bind为:

kernel.Bind<Service>().ToMethod(()=>kernel.Get<IService>()).InSingletonScope();
Run Code Online (Sandbox Code Playgroud)

重复循环引用和混淆等.在内部,隐式自绑定将为Service添加隐式绑定注册.你应该发布例外.

编辑:重新评论.如果你这样做:

Func<Service> serviceCreator = () => new Service(false);
kernel.Bind<Service>().ToMethod(serviceCreator).InSingletonScope();
kernel.Bind<IService>().ToMethod(()=>kernel.Get<Service>()).InSingletonScope();
Run Code Online (Sandbox Code Playgroud)

然后在IService获得Resolved 时不会生成隐式的Class Self Binding - 它使用现有的.

有其他Nexus Q在这里所以在最近几周有人在做这种类型的事情,但也陷入了与IInitializable一个问题 -这个例子将有正确的排序,但根据我的源阅读和方式的一个以上有道理它生成隐式类自绑定.


Str*_*ior 5

顺便说一句,Ninject 3 允许这种语法:

kernel.Bind<IService, Service>().ToMethod(serviceCreator).InSingletonScope();
Run Code Online (Sandbox Code Playgroud)

或者,类似地:

kernel.Bind(typeof(IService), typeof(Service)).ToMethod(serviceCreator).InSingletonScope();
Run Code Online (Sandbox Code Playgroud)

如果您有许多服务,或者如果您在运行时动态发现服务(后者可以params直接将-style参数作为数组传递),后一种方法可以更好地工作.

  • 这是可行的方法,但在最初提出问题时可能无法使用. (2认同)
  • 抱歉,我猜是有点太急切了。对于 Bind,有一个重载 `Bind(params Type[] services)` 接受(几乎)任意数量的类型。`Bind&lt;IX, IFoo&gt;` 最多支持 4 种类型。因此,如果您有超过 4 种类型,或者当您使用反射来获取类型时,另一个重载是有益的。您能否用更好的“措辞”将其添加到您自己的答案中?恕我直言,这将使答案完整。 (2认同)