2013-03-14 2 views
15

Я пытаюсь понять шаблон фабрики делегатов с Autofac. Я знаю, как реализовать завод с использованием IIndex <> с шпоночным() регистрации, что объясняется хорошо здесь: Configuring an Autofac delegate factory that's defined on an abstract classФабрика делегатов Autofac, использующая func <>

Я хотел бы знать, если я могу создать завод, используя Func <>, и как бы я сделать регистрация для следующего образца:

public enum Service 
{ 
    Foo, 
    Bar 
} 

public interface FooService : IService 
{ 
    ServiceMethod(); 
} 

public interface BarService : IService 
{ 
    ServiceMethod(); 
} 

public class FooBarClient 
{ 
    private readonly IService service; 

    public FooBarClient(Func<Service, IService> service) 
    { 
     this.service = service(Service.Foo); 
    } 

    public void Process() 
    { 
     service.ServiceMethod(); // call the foo service. 
    } 
} 
+0

Почему вы не просто использовать 'IIndex <>' с 'Keyed()'? Autofac не может создать этот 'Func ' для вас. Вам необходимо зарегистрировать его в своем контейнере с помощью 'Keyed()' или 'Named()' что-то вроде: 'builder.Register > (c => s => c.ResolveKeyed (s)); 'Делегатные заводы могут создавать только один тип с параметрами и не выбирать тип, основанный на параметре, потому что это то, что является' IIndex <> 'for. – nemesv

+2

Для IIndex <> Мне нужно будет указать библиотеку Autofac, которую я пытаюсь избежать. Я хочу, чтобы мой код DI был в Composite root (отдельная библиотека) только по возможности. –

ответ

16

Autofac не может построить этот Func<Service, IService> для вас, которая позволяет возвращать различные типы на основе параметра. Это то, что для IIndex<> для.

Однако, если вы не хотите/не можете использовать IIndex<> вы можете создать эту функцию на заводе с помощью Keyed или Named и зарегистрировать свой завод в контейнере:

var builder = new ContainerBuilder(); 
builder.RegisterType<FooBarClient>().AsSelf(); 
builder.RegisterType<FooService>().Keyed<IService>(Service.Foo); 
builder.RegisterType<BarService>().Keyed<IService>(Service.Bar); 

builder.Register<Func<Service, IService>>(c => 
{ 
    var context = c.Resolve<IComponentContext>(); 
    return s => context.ResolveKeyed<IService>(s); 
}); 
+0

спасибо nemesv! его работа как ожидалось !!! jus один вопрос, будет ли разница в производительности - IIndex vs Func? –

+0

Я не знаю, как реализована версия IIndex и какая у нее есть chaching или оптимизация производительности. Вы можете проверить имплантацию, или вам нужно выполнить тесты производительности, адаптированные для вашего сценария, чтобы сравнить их. – nemesv

+2

Я просто попробовал это по причине версии, но это дает мне «ObjectDisposedException» ... Я «разрешил» это, вызвав «новый Foo» внутри делегата (который является biiiig nogo!) –

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