0

假设在 C# 中我有一个名为 A 的类

public class A : IInterfaceA
{

 [Dependency]
 B _b;


}

然后在 B 类中,我有一个这样的构造函数:

public class B
{

...

 public B(string someParam) { ... }

...

}

现在,我像这样注册 A 类:

_unityContainer.RegisterType<IInterfaceA, A>("RegistrationA");

并解决我做的界面:

_unityContainer.Resolve<IInterfaceA>("RegistrationA", new ParameterOverride("someParam", "The param."));

现在我想知道解决类并像这样传递参数是否是一种好习惯,或者我应该以另一种方式来做。非常感谢 :)

4

1 回答 1

0

首先,您发布的代码不起作用:实际上您正在覆盖 class 的参数A,而在您的代码中,带有参数的构造函数是B.

一般来说,在我看来,使用参数覆盖不是一个好习惯(除非一些非常特殊的上下文,如控制台应用程序或使用现有容器的 Web 服务,但在大多数情况下是可以避免的),原因如下:

  1. 使用Resolve看起来像服务定位器:如今的反模式。你会发现很多关于谷歌的讨论。
  2. 使用 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();

现在,在一个大型应用程序中,您将需要很多类似的工厂。为了避免抽象工厂和实现的样板代码,您可以在网络上找到一些自动抽象工厂扩展的实现。

于 2013-11-21T23:46:06.177 回答