2013-09-12 4 views
0

У меня есть класс строителя, который имеет статус.Есть ли умный способ использования переходного объекта в одноэлементном режиме?

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

class FilterBuilder : IFilterBuilder { //implementation } 

На данный момент я создаю свои экземпляры с новым ключевым словом, потому что это недолгий и используется внутри метода одноплодного объекта.

Я знаю, что могу ввести заводской тип, например 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

Я думаю, что лучше просто использовать filterBuilderFactory, чем пытаться сделать эту работу с контейнером IOC. – driushkin

ответ

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 для создания такого класса для вас для любого интерфейса.

+0

Это создаст новый экземпляр для каждого вызова экземпляра. Я потеряю государство. FilterBuilder хранит список фильтров внутри, я строю список пошагово. –

+1

Ну, вы хотели временного поведения, не так ли? Возможно, вам придется пересмотреть свой дизайн. – Steven

+0

Ну, не то, что преходяще :). Мне нужно только получить метод переопределения свойства. –

1

Сначала вы должны хранить контейнер где-то после настройки. , например

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

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

The вы можете использовать переходные процессы в одноэлементных, как это:

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

Таким образом, каждый раз, когда вы доступ FilterBuilder свойство она будет решена, как вы настроили.

Смежные вопросы