答案 0 :(得分:3)
您正在寻找的是“工厂适配器”或Func< T,U&gt ;.
需要动态创建另一个组件的参数化实例的组件使用Func< T,U>依赖类型来表示:
class Bar
{
Func<string, int, IFoo> _fooCreator;
public Bar(Func<string, int, IFoo> fooCreator) {
_fooCreator = fooCreator;
}
public void Go() {
var foo = _fooCreator("a", 42);
// ...
}
}
例如,只要注册了IFoo,Autofac就会自动提供Func。它还会将参数合并到Foo构造函数(包括ILogger)中,并丢弃任何不必要的内容而不是抛出错误。
Autofac还支持自定义代理,如:
delegate IFoo FooCreator(string alpha, int omega);
这样可以重写Bar:
class Bar
{
FooCreator _fooCreator;
public Bar(FooCreator fooCreator) {
_fooCreator = fooCreator;
}
public void Go() {
var foo = _fooCreator("a", 42);
// ...
}
}
使用自定义委托时,参数将按名称匹配,而不是与Func匹配。
Autofac有一些您可以查看的文档:http://code.google.com/p/autofac/wiki/DelegateFactories。
在几个IOC容器社区之间有一个名为“公共上下文适配器”的协作项目,用于标准化这些和其他高阶依赖类型。项目网站位于http://cca.codeplex.com。
CCA提出的第一个规范涵盖了工厂适配器,您可以在此处阅读:http://cca.codeplex.com/wikipage?title=FuncFactoryScenarios&referringTitle=Documentation。
您可能会发现其他一些有用的链接:
http://nblumhardt.com/2010/04/introducing-autofac-2-1-rtw/ http://nblumhardt.com/2010/01/the-relationship-zoo/
我希望你会发现虽然IoC容器在它们完全透明之前还有很长的路要走,但实际上我们很难到达那里:)
尼克
答案 1 :(得分:0)
如果这些参数在应用程序的生命周期内是常量,那么您可以添加IConfigurationService,其唯一目的是将这些参数返回给需要它们的任何人。 IConfigurationService的实现可能具有硬编码值,从配置文件中读取它们......等等。当然,IConfigurationService的实现是通过IoC容器检索的。
如果这些参数因实例而异,那么我认为它们不应作为IoC容器加载的对象的构造函数参数提供。这使得所有组件都需要查找/依赖IoC容器,这首先会破坏IoC容器的位置。
通过公开setter方法使它们在对象本身上可配置(当它们可能在对象的生命周期内发生变化时适当)或者将它们作为返回对象的工厂方法的参数(工厂对象所在的位置)在您的IoC容器中注册。)
你对使用工厂犹豫不决,但我认为这是一种优雅的方法。是的,它需要努力创建一个工厂,但由于有一个要求支持该行为,它不是代码膨胀。它是一个满足要求的简单模式。