将一个类绑定到多个接口作为单例模式

18

我例如有两个接口IInterface1IInterface2,

public interface IInterface1 {...}
public interface IInterface2 {...} 

还有这些接口的一个实现ImplClass

public class ImplClass : IInterface1, IInterface2 {...}

我必须确保应用程序只有一个ImplClass实例,该实例将用作IInterface1和IInterface2。我正在使用ninject进行依赖注入。因此,我的问题是:下面的代码是否满足我的要求?

...
Bind<IInterface1>().To<ImplClass>().Using<SingletonBehavior>();
Bind<IInterface2>().To<ImplClass>().Using<SingletonBehavior>();
...

或者这段代码会为每个接口创建 2 个 ImplClass 实例吗?


将单例绑定到Ninject中的多个服务的副本 - Pete
@Pete,你能否实际投票关闭(好决定顺便说一句)? - Ruben Bartelink
4个回答

20

使用 Ninject,您可以这样做:

var impl = new Impl();
container.Bind<IInt1>().ToMethod(c => impl);
container.Bind<IInt2>().ToMethod(c => impl);

Impl类有无法使用Ninject进行注入的依赖项时,您可以这样做:

container.Bind<Impl>().ToSelf().InSingletonScope();
container.Bind<IInt1>().ToMethod(c => c.Kernel.Get<Impl>());
container.Bind<IInt2>().ToMethod(c => c.Kernel.Get<Impl>()); 

简洁明了。


我喜欢它。你不必将类设置为实际的单例,但是你保证只提供一个实例。 - KeithS
-1这不是一个好的通用解决方案,因为每个解析都会导致激活,请参见https://dev59.com/mXA75IYBdhLWcg3w6Ndj。 - Ruben Bartelink
4
在Ninject中,是否有可能将不同的接口绑定到同一个类的实例? - Ruben Bartelink
请参考Daan的下面的答案 - Ninject v3现在为您提供了一种更优雅的方法来实现这一点 :) - Efrain

5

看起来你仍在使用Ninject 1.5。我不记得确切的语法了,但应该类似于以下2.1语法:

kernel.Bind<I1>().ToMethod(ctx => ctx.Kernel.Get<Impl>());
kernel.Bind<I2>().ToMethod(ctx => ctx.Kernel.Get<Impl>()); 
kernel.Bind<Impl>().ToSelf().InSingletonScope();

甚至更好的方法是使用Ninject.Extensions.ContextPreservation来保留上下文。
kernel.Bind<Impl>().ToSelf().InSingletonScope();
kernel.BindInterfaceToBinding<I1, Impl>();
kernel.BindInterfaceToBinding<I2, Impl>();

@JeffWalkerCodeRanger 请解释。 - Remo Gloor
曾经点赞,现在想改为踩,因为它是一个重复的问题,与 https://dev59.com/t2855IYBdhLWcg3wsWlq#4195510 相同(并且有相同的多次激活问题)。 - Ruben Bartelink

3

1
我会怀疑这会创建两个实例。
试试看下面的结构是否适用于你:
public class ImplClass : IInterface1, IInterface2
{
    public static readonly ImplClass Instance = new ImplClass();
}

使用以下绑定:

Bind<IInterface1>().ToMethod(c => ImplClass.Instance);
Bind<IInterface2>().ToMethod(c => ImplClass.Instance);

2
好的回答,+1。但是在我看来,IoC框架的优点之一是可以设置单例对象,而不必实际定义类结构作为单例(这样更容易在以后改变主意,或在不同环境中设置容器或工厂范围的注册)。如果他只是在Binding类中初始化一个类并将其注册为单个实例范围,那该怎么办?(我不太了解Ninject的能力,但Autofac没有问题)。 - KeithS

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接