2012-03-12 5 views
5

У меня есть репозиторий автокрепеж NhRepositoryFactoryКак придать завод родовых типов с Autofac

public interface IRepositoryFactory 
{ 
    IRepository<T> Create<T>() where T: Entity; 
} 

public class NhRepositoryFactory: IRepositoryFactory 
{ 
    public IRepository<T> Create<T>() where T : Entity 
    { 
    return new NhRepository<T>(); 
    } 
} 

Для решения некоторых репозиториев зависимостей, которые я хочу, чтобы получить их из контейнера Autofac. Поэтому я должен как-то ввести Func<IRepository<T>> завод в свой класс. Как я могу это сделать?
Спасибо заранее.

+0

Почему вы не храните контейнер Autofac внутри 'NhRepositoryFactory'? – Steven

+2

Я хочу, чтобы мой завод был Autofac-агностиком. –

+0

Он содержит только одну строку кода. Вы можете поместить его в свой корень композиции. Он не обязательно должен быть контейнерным агностиком. – Steven

ответ

5

NhRepositoryFactory не содержит бизнес-логики и может быть частью вашего корня композиции. Это позволяет вам иметь ссылку на контейнер. This is just mechanics и не считается анти-шаблоном Service Locator. NhRepositoryFactory будет выглядеть следующим образом:

// This class is part of your composition root 
public class NhRepositoryFactory : IRepositoryFactory 
{ 
    private readonly Container container; 

    public NhRepositoryFactory(Container container) 
    { 
     this.container = container; 
    } 

    public IRepository<T> Create<T>() where T : Entity 
    { 
     return this.container.Resolve<NhRepository<T>>(); 
    } 
} 

И вы можете зарегистрировать его, как это:

+0

Я согласен с тем, что кажется неизбежным пара с Autofac так или иначе. Я сделал это так, как вы предлагали. Разница в том, что я передал 'ILifetimeScope' вместо' Container'. –

+0

Я изменил реализацию. Я создал интерфейс 'IObjectFactory' с помощью' T Create () 'метода, который использует' ILifetimeScope' для создания объектов. Он реализуется классом 'AutofacObjectFactory', который вводится в' NhRepositoryFactory'. Так что теперь нет Autofac-сцепления. –

+0

После рефакторинга 'IRepositoryFactory' был удален. Его место заняло 'IObjectFactory'. –

4

Autofac также способен обрабатывать родовое создание изначально без завода.

builder.RegisterGeneric(typeof(NhRepository<>)) 
    .As(typeof(IRepository<>)) 
    .InstancePerLifetimeScope(); 

Используя этот шаблон, вы можете просто зависеть от IRepository и autofac заполнить зависимости.

+1

Я пробовал это так. Но когда в каком-то классе понадобилось несколько репозиториев, я должен был добавить их в качестве параметров конструктора. Также должно было быть создано поле для каждого из них. Это казалось неуклюжим, поэтому я создал завод. –

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