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

Register types in UnityContainer to use other named registrations to resolve constructor parameters

假设我有一个 class 依赖于接口 IFace 以及注入到构造函数中的其他几个依赖项(由 ... 描述)。我还有 2 个 IFace 接口的实现。

class Impl1 : IFace {}
class Impl2 : IFace {}

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

我想将 Impl1 注册为默认实现并将 Impl2 注册为应注入某些 classes 的命名实现。

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, ...)));

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

我想要的是:(InjectNamedType 显然是虚构的)

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

以下是您的操作方法:

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

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

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