是否有一种聪明的方法在单例中使用瞬态对象?

时间:2013-09-12 20:05:56

标签: c# dependency-injection castle-windsor

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

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;

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

2 个答案:

答案 0 :(得分: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属性时,都将按照您的配置进行解析。

答案 1 :(得分: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为任何接口生成此类。