Unity将两个接口注册为一个单例

Chr*_*ert 42 unity-container

如何在Unity中使用相同的实例注册两个不同的接口...目前我正在使用

        _container.RegisterType<EventService, EventService>(new ContainerControlledLifetimeManager());
        _container.RegisterInstance<IEventService>(_container.Resolve<EventService>());
        _container.RegisterInstance<IEventServiceInformation>(_container.Resolve<EventService>());
Run Code Online (Sandbox Code Playgroud)

哪个有效,但看起来不太好..

所以,我认为你明白了.EventService实现了两个接口,如果我解析接口,我想要对同一个对象的引用.

克里斯

Sve*_*ler 57

[编辑]

可以在此处找到通过XML配置执行此操作的解决方案.基于该答案,我建议采用简化的仅代码方法,如下所示:

_container.RegisterType<IEventService, EventService>(new ContainerControlledLifetimeManager());
_container.RegisterType<IEventServiceInformation, EventService>(new ContainerControlledLifetimeManager());
bool singleton = ReferenceEquals(_container.Resolve<IEventService>(), _container.Resolve<IEventServiceInformation>());
Run Code Online (Sandbox Code Playgroud)

这样,容器不会发布EventService类本身.由于该类应被视为实现细节,因此这是更好的方法.

[原始答案]

有点迟到的答案,但应该做的诀窍:

_container.RegisterType<EventService>(new ContainerControlledLifetimeManager());
_container.RegisterType<IEventService, EventService>();
_container.RegisterType<IEventServiceInformation, EventService>();

bool singleton = ReferenceEquals(_container.Resolve<IEventService>(), _container.Resolve<IEventServiceInformation>());
Run Code Online (Sandbox Code Playgroud)

  • 有趣的是,(至少在这里)似乎在将其中一个设置为命名注册时它不起作用...... (7认同)
  • 我遵循了您为Unity 5.10编辑的答案,结果证明不是单例。因此,除非我做错了什么,否则这个答案可能会过时。 (2认同)

And*_*mes 15

编辑

在评论中得到一些反馈后,我认为Sven的答案是一个非常优秀的答案.感谢Chris Tavares指出技术优点.


这几乎是唯一的方法.

你可以稍微修改它(我讨厌每个泛型参数的RegisterType类型相同):

EventService es = _container.Resolve<EventService>();
_container.RegisterInstance<IEventService>(es);
_container.RegisterInstance<IEventServiceInformation>(es);
Run Code Online (Sandbox Code Playgroud)

如果您的一个或多个IoC孩子要请求具体EventService类型(希望不是),您可以再添加一个RegisterInstance类型RegisterInstance<EventService>.希望你不需要那个,所有的依赖对象都要求一个IEventService,而不是一个EventService.

希望这有帮助,安德森

  • 依赖注入是一种很好的做法,可以尽可能地将布线时间与解决时间分开.这个解决方案的缺点是它需要你调用'resolve'调用'register'来调用'register' (6认同)
  • @Anderson - 嗯,这种方法确实有效,但它有两个不良的副作用.首先,两个RegisterInstance调用导致两个生命周期管理器,这意味着将在对象上调用两次Dispose.根据类型,这可能是也可能不是问题.另一个问题是:如果EventService本身有依赖关系怎么办?在这种情况下,在确定所有EventService的依赖项都已在容器中注册之后,才能执行Resolve调用.使用RegisterType方法,您可以随时注册它. (6认同)
  • 这真的不是要走的路 - 请改用下面的Sven Kunzler的答案. (3认同)

Con*_*ole 7

对于这么简单的事情,适配器方法似乎很笨重,所以我看得更远一点.要解决命名实例的问题,您需要注册类型,并注册接口的工厂.

 InjectionFactory factory = new InjectionFactory(x => x.Resolve<SimulationService>());
 this.Container.RegisterType<SimulationService>(new ContainerControlledLifetimeManager());
 this.Container.RegisterType<IContentProvider>("SimulationContentProvider", factory);
 this.Container.RegisterType<ISimulationService>(factory);
Run Code Online (Sandbox Code Playgroud)

这样您就不需要创建具体类的实例(在注册时),由于缺少依赖性,这在我的情况下是不可能的.