IOC容器处理非默认构造函数中的状态参数

时间:2010-04-16 23:06:41

标签: parameters constructor ioc-container code-contracts design-by-contract

2 个答案:

答案 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容器中注册。)

你对使用工厂犹豫不决,但我认为这是一种优雅的方法。是的,它需要努力创建一个工厂,但由于有一个要求支持该行为,它不是代码膨胀。它是一个满足要求的简单模式。