Castle Windsor IOC:将构造函数参数传递给子组件

Mou*_*awa 6 .net castle-windsor

以下代码仅用于演示目的.

假设我有2个组件(businessService和dataService)和一个UI类.

UI类需要业务服务,businessService需要dataService,而dataService需要依赖connectionString.

形成我需要解析业务服务的UI类,所以我写下面的代码:

var service = container.Resolve<BusinessService>(new { dependancy = "con string 123" }));
Run Code Online (Sandbox Code Playgroud)

请注意,dependance是connectionString构造函数参数.

但上面的代码不起作用,说dataService期望依赖性不满意.

无法创建组件'dataService',因为它具有要满足的依赖性.dataService正在等待以下依赖项:

密钥(具有特定密钥的组件) - 未注册的依赖性.

所以作为一种解决方法我这样做:

var service = container.Resolve<BusinessService>(new { dataService = container.Resolve<IDataService>(new { dependancy = "123" }) });
Run Code Online (Sandbox Code Playgroud)

但是从设计,编码风格和许多角度来看,这不是一个很好的方法.

所以,如果您可以建议为什么它不能以简单的方式工作或者您有更好的解决方法请分享.

Krz*_*mic 6

你看到的行为是设计的.

有两种方法可以解决问题,具体取决于您想要传递的值的动态程度.

文档做得非常好,详细说明,所以我在此不再重复.

更新

为了清楚起见 - Windsor不会在分辨率管道中传递内联参数.原因很简单 - 这样做会破坏抽象.调用代码必须隐式知道您的BusinessService依赖DataService取决于连接字符串.

如果你绝对必须这样做,那就明白了.这就是你正在做的事情 - DataService明确地解决它对连接字符串的依赖,并显式解析BusinessService传递DataServiceas依赖.

为了使事情真正明确(并且更好地使用)我建议使用Typed Factory而不是直接调用容器

public interface IFactory
{
   IDataService ResolveDataService(string connectionString);
   IBussinessService ResolveBussinessService(IDataService dataService);
   // possibly release method for IBussinessService as well
}
Run Code Online (Sandbox Code Playgroud)

  • @Moutasem al-awa:简而言之,你正试图做一些在99%的情况下做坏事的事情.避免直接调用`Resolve()`(因为你正在进行服务定位而不是依赖注入),你会看到正确的方法. (2认同)