在UnityContainer中注册类型以使用其他命名注册来解析构造函数参数

本文关键字:注册 构造函数 参数 UnityContainer 类型 其他 | 更新日期: 2023-09-27 18:30:13

假设我有一个类,它依赖于接口IFace,并将其他几个依赖项注入构造函数(如...所示)。我还有两个IFace接口的实现。

class Impl1 : IFace {}
class Impl2 : IFace {}
class Std : IStd {
    Std(IFace impl1, IOtherDependency otherDep, ...) { ... }
}

我想将Impl1注册为默认实现,将Impl2注册为命名实现,应该将其注入到某些类中。

container.RegisterType<IFace, Impl1>();
container.RegisterType<IFace, Impl2>("impl2");

像这样注册Std将注入默认的Impl1实现:

container.RegisterType<IStd, Std>(); // this would inject the default implementation Impl1

如何注册Std以注入命名实现,而不需要手动调用Resolve()?我能想到的最好的办法是:

container.RegisterType<IStd, Std>(
    new InjectionConstructor(new ResolvedParameter<IFace>("impl2"), typeof(IOtherDependency, ...)));

我不喜欢上述方式的地方是,我仍然需要指定所有其他构造函数参数;当签名更改时,我需要调整注册,编译器不会发现问题(抛出运行时异常),intellisense在这里也不起作用。

我想要的是:(InjectNamedType显然是由组成的)

container.RegisterType<IStd, Std>(
    InjectNamedType<IFace>(name: "impl2")); // this would tell Unity to look for registration of IFace with that name

在UnityContainer中注册类型以使用其他命名注册来解析构造函数参数

以下是如何做到这一点:

container.RegisterType<IStd>(
    new InjectionFactory(x =>
        x.Resolve<Std>(new DependencyOverride<IFace>(x.Resolve<IFace>("impl2")))));

InjectionFactory允许您指定创建IStd对象的工厂逻辑。我们使用Resolve方法来解析具体的Std类,并使用DependencyOverride类来指定要使用IFace的哪个实现。我们再次使用Resolve方法来解决特定的实现。

请注意,只有当有人试图解析IStd(或依赖于IStd的类)时,工厂逻辑才会运行,而不是当您注册IStd时。