注入(通过构造函数)实现相同接口的不同类型的正确方法是什么?

时间:2014-12-05 02:28:17

标签: unity-container

例如,我们说我有一个界面' IFeed'以及实现此接口的两种具体类型(' Feed1'和#39; Feed2')。现在让我们说我有一个FeedManager'带有多个将动态解析的参数的类型,其中两个类型为' IFeed'并且我喜欢通过构造函数注入注入的具体类型, not 通过手动解析(我只在组合根处使用resolve一次)。我有一种感觉,我应该使用工厂,但我想看看这样做的正确方法是什么。非常感谢提前。

3 个答案:

答案 0 :(得分:0)

假设您想在运行时确定实际的具体实例,您需要使用命名类型注册,然后告诉Unity你想要哪一个。因此,使用工厂方法构造所需的类型并将其作为参数覆盖传递。 Unity将使用覆盖并解决任何剩余的依赖项。

 // register the types using named registrations
container.RegisterType<IFeedManager,FeedManager>()
container.RegisterType<IFeed, Feed1>("Feed1")
container.RegisterType<IFeed, Feed2>("Feed2")

假设您的Feed管理器具有以下命名构造函数参数

class FeedManager : IFeedManager
{
   public FeedManager (IFeed Feed1, IFeed Feed2, string someOtherDependency)
   {
   }
}

并创建您的Feed管理器:

static IFeedManager CreateFeedManager()
{

    ParameterOverride feed1 = new ParameterOverride("Feed1"
                         ,_container.Resolve<IFeed>("feed1"));

    ParameterOverride feed2 = new DependencyOverride("Feed2"
                         ,_container.Resolve<IFeed>("feed2"));

    IFeedManager = _container.Resolve<IFeedManager>(feed1,feed2)

    return IFeedManager;
}

显然这是过度简化的,但是您插入自己的逻辑来确定要解析的实例,然后为FeedManager所需的每个IFeed实例注入。

答案 1 :(得分:0)

使用Unity,您可以这样做:

container.RegisterType<IFeed, Feed1>("Feed1");
container.RegisterType<IFeed, Feed2>("Feed2");
container.RegisterType<FeedManager>(new InjectionConstructor(new ResolvedParameter<IFeed>("Feed1"),
    new ResolvedParameter<IFeed>("Feed2")));

现在已配置Unity,以便在需要解析FeedManager时,它将解析第一个参数的Feed1和第二个参数的Feed2。

答案 2 :(得分:0)

如果你想要IFeed的所有实现,你可以在构造函数中使用数组语法,然后在类型注册时不需要特殊的东西。

container.RegisterType<IFeedManager, FeedManager>();
container.RegisterType<IFeed, FeedA>("FeedA"); // The name doesn't matter
container.RegisterType<IFeed, FeedB>("FeedB"); // The name doesn't matter

然后是经理构造函数......

public FeedManager(IFeed[] feeds) {...}

或者如果你想直接调用构造函数添加一点点光晕......

public FeedManager(params IFeed[] feeds) {...}