首先,您发布的代码不起作用:实际上您正在覆盖 class 的参数A
,而在您的代码中,带有参数的构造函数是B
.
一般来说,在我看来,使用参数覆盖不是一个好习惯(除非一些非常特殊的上下文,如控制台应用程序或使用现有容器的 Web 服务,但在大多数情况下是可以避免的),原因如下:
- 使用
Resolve
看起来像服务定位器:如今的反模式。你会发现很多关于谷歌的讨论。
- 使用 ParameterOverride 意味着客户端(Resolve 的调用者)确切地知道容器中映射的类型,并希望使用特定参数初始化该类型。但这与控制反转正好相反。
最好的方法是使用抽象工厂。您可以添加代码并使用更灵活和 SOLID 的抽象工厂:
public interface BFactory {
B Create(string bparam);
}
public class BFactoryUnity : BFactory {
private IUnityContainer container;
public BFactoryUnity(IUnityContainer container) {
this.container = container;
}
public B Create(String bParam) {
var b = new B(bParam);
container.BuildUp(b);
return b;
}
}
所以你可以注册:
_unityContainer.RegisterType<IInterfaceA, A>("RegistrationA")
.RegisterType<BFactory, BFactoryUnity>();
现在客户端只能解析工厂并使用它:
var bFactory = _container.Resolve<BFactory>();
var b = bFactory.Create();
现在,在一个大型应用程序中,您将需要很多类似的工厂。为了避免抽象工厂和实现的样板代码,您可以在网络上找到一些自动抽象工厂扩展的实现。