0

我有一个有状态的构建器类。

interface IFilterBuilder
{
     AddFilter1();
     AddFilter2();
     //etc
     IEnumerable<Filter> FilterList { get; }
}

class FilterBuilder : IFilterBuilder { //implementation }

目前我正在使用 new 关键字创建它的实例,因为它是短暂的,并且在单例对象的方法中使用。

我知道我可以注入像Func<IFilterBuilder>单例这样的工厂类型并用容器解决它,但我真的不想拥有一个filterBuilderFactory.

有没有办法通过这样的拦截来做某种魔术:

class SingletonClass
{
    [TransientDependency]
    public IFilterBuilder FilterBuilder
    get 
    { 
        //magic.gif
    }
    set
    {
        //some stuff for testability
    }
}

因此,当我需要在方法中使用它时,我会得到一个新实例。

IFilter filterBuilder = FilterBuilder;
filterBuilder.AddFilter1();
return filterBuilder.FilterList;

当它超出范围时,它必须释放对象,我应该有办法在我的测试中用模拟替换它。

4

2 回答 2

1

首先,您必须在配置后将容器存储在某处。例如

public static class IoC
{
    public static IWindsorContainer Container { get;set; }
}

var container = new WindsorContainer().Install(
    FromAssembly.This()
);
IoC.Container = container;

您可以像这样在单例中使用瞬变:

class SingletonClass
{
    public IFilterBuilder FilterBuilder
    {
        get 
        { 
            return IoC.Container.Resolve<IFilterBuilder>();
        }
    }
}

因此,每次您访问 FilterBuilder 属性时,它都会按照您的配置进行解析。

于 2013-09-17T21:21:44.627 回答
0

您正在寻找的是代理对象。手动实现时,它将如下所示:

public class FilterBuilderProxy : IFilterBuilder
{
    private Func<IFilterBuilder> factory;
    public FilterBuilderProxy(Func<IFilterBuilder> factory) 
    { 
        this.factory = factory; 
    }

    AddFilter1() { this.factory.Invoke().AddFilter1(); }
    AddFilter2() { this.factory.Invoke().AddFilter2(); }
    // etc
}

现在您可以将它注入FilterBuilderProxy到单例中,它将确保使用真正的瞬态IFilterBuilder实现。

我认为没有任何 IoC 容器对此提供开箱即用的支持,但您当然可以使用 CastleDynamicProxy 为任何接口生成此类。

于 2013-09-12T21:50:57.457 回答