使用DryIoc创建具有多个服务注册的单例

时间:2016-08-29 19:59:16

标签: c# dryioc

问题

我尝试使用DryIoc注册单例,但容器正在返回我的单例类的多个实例。单例类被注册为多个不同服务接口的实现类型。当从DryIoc请求任何上述服务接口时,我希望得到我的单身类的相同实例,但这没有发生,我不知道为什么。

示例

这是我尝试做的一个基本示例。在这个例子中,我有一个类Foo,我想用它作为接口IFooIBar的单例实现。换句话说,当从容器中解析IFooIBar时,我希望返回相同的Foo实例。

服务接口

interface IFoo
{   
}
interface IBar
{   
}

单身(实施)类

class Foo : IFoo, IBar
{
}

测试

Container container = new Container();
container.Register<IFoo, Foo>(Reuse.Singleton);
container.Register<IBar, Foo>(Reuse.Singleton);

object foo = container.Resolve<IFoo>();
object bar = container.Resolve<IBar>();
Assert.AreSame(foo, bar); // Why does this fail?

考虑解决方案

我考虑过使用DryIoc的RegisterInstance方法,但这需要手动创建类,我试图避免这种情况,因为与上面的简化示例不同,现实世界中有自己的依赖。

2 个答案:

答案 0 :(得分:4)

Register方法向容器添加单独/独立的注册。您需要明确地说对多个服务使用相同的注册。

选项1:RegisterMany

// registers with Foo interfaces and itself. Remove @nonPublicServiceTypes to restrict for public types
container.RegisterMany<Foo>(Reuse.Singleton, nonPublicServiceTypes: true);

Assert.AreSame(container.Resolve<IFoo>(), container.Resolve<IBar>());

选项2:RegisterMapping

container.Register<IFoo, Foo>(Reuse.Singleton);
container.RegisterMapping<IBar, IFoo>(); // maps to the IBar registration

Assert.AreSame(container.Resolve<IFoo>(), container.Resolve<IBar>());

其他:

手动委派分辨率,如@Fyodor answer。

答案 1 :(得分:1)

DryIoc的“重用”概念适用于服务,而不是实现。您的注册适用于两种不同的服务(IFooIBar),因此它们会重复使用,并且它们共享实施(Foo)的事实不适用于此。

为了实现您的目标,您可以通过重定向到实施的made注册服务:

container.Register<Foo>( Reuse.Singleton );
container.Register<IFoo, Foo>( made: Made.Of( () => ReturnThis( Arg.Of<Foo>() ) ), reuse: Reuse.Singleton );
container.Register<IBar, Foo>( made: Made.Of( () => ReturnThis( Arg.Of<Foo>() ) ), reuse: Reuse.Singleton );

// Where ReturnThis is define thusly:
static T ReturnThis<T>( T t ) => t;

(您需要ReturnThis来电,因为裸Made.Of( () => Arg.Of<Foo>() )无效; Made总是需要方法调用)