Unity的依赖属性和构造函数参数

时间:2013-11-15 10:25:10

标签: c# unity-container

让我们在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."));

现在我想知道解析类并传递这样的参数是否是一个好习惯,或者我应该采用另一种方式。 非常感谢:)

1 个答案:

答案 0 :(得分:0)

首先,您发布的代码不起作用:实际上您覆盖了类A的参数,而在代码中,参数的构造函数为B

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

  1. 使用Resolve看起来像服务定位器:现在是反模式。你会发现很多关于谷歌的讨论。
  2. 使用ParameterOverride意味着客户端(Resolve的调用者)确切地知道容器中映射的类型,并希望使用特定参数初始化该类型。但这与控制反转正好相反。
  3. 最好的方法是使用抽象工厂。您可以添加代码并使用更灵活的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();
    

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