Unity:如何注入带有两个接口的单例,其中一个类型映射需要命名

本文关键字:一个 类型 映射 单例 接口 何注入 注入 Unity 两个 | 更新日期: 2023-09-27 18:03:04

我的问题是这个的变化:Unity注册两个接口作为一个单例

在我的例子中,注入的单例组件有两个接口,但其中一个接口用于映射多个命名的具体类型。

例如,我的组件需要作为依赖项,一组(命名的)IEventSources和一个IEventManager(它本身也是一个IEventSource):

  public interface IEventManager { }
  public interface IEventSource { }
  public class EventManager : IEventManager, IEventSource { }
  public class EventSourceA : IEventSource { }
  public class EventSourceB : IEventSource { }
  public class Component
  {
    public Component(IEventManager eventManager, IEventSource[] eventSources)
    {
      Debug.Assert(eventSources.Contains((IEventSource) eventManager));
    }
  }
  class Program
  {
    static void Main()
    {
      var container = new UnityContainer();
      container.RegisterType<IEventManager, EventManager>(new ContainerControlledLifetimeManager());
      container.RegisterType<IEventSource, EventManager>("EventManager", new ContainerControlledLifetimeManager());
      container.RegisterType<IEventSource, EventSourceA>("EventSourceA");
      container.RegisterType<IEventSource, EventSourceB>("EventSourceB");
      container.RegisterType(typeof(Component));
      container.Resolve<Component>();
    }
  }

或者,我最终需要从app.config配置:

  <unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
    <container>
      <register type="IEventManager" mapTo="EventManager">
        <lifetime type="singleton" />
      </register>
      <register name="EventManager" type="IEventSource" mapTo="EventManager">
        <lifetime type="singleton" />
      </register>
      <register name="EventSourceA" type="IEventSource" mapTo="EventSourceA" />
      <register name="EventSourceB" type="IEventSource" mapTo="EventSourceB" />
      <register type="Component" />
    </container>
  </unity>

这里创建了两个EventManager实例,断言失败。我想确保同一个实例满足两个组件依赖。

我可以让组件只接受IEventSource实例,并在运行时从中取出单个IEventManager实例,但这似乎很脆弱,对我来说很糟糕。是否有办法利用Unity实现这一点?

Unity:如何注入带有两个接口的单例,其中一个类型映射需要命名

如果您像下面这样更改Main中的注册代码,则断言将通过。这样够吗?

        var container = new UnityContainer();
        var manager = container.Resolve<EventManager>();
        container.RegisterInstance<IEventManager>(manager, new ContainerControlledLifetimeManager());
        container.RegisterInstance<IEventSource>("EventManager", manager, new ContainerControlledLifetimeManager());
        container.RegisterType<IEventSource, EventSourceA>("EventSourceA");
        container.RegisterType<IEventSource, EventSourceB>("EventSourceB");
        container.RegisterType(typeof(Component));
        container.Resolve<Component>();