2015-02-13 2 views
1

Я использую Autofac в своем проекте. Я хочу использовать простой интерфейс для их решения. Не общий репозиторий.Конструктор AutoFac несколько Интерфейс

Я использовал замок в своих старых проектах. Он имеет класс, который имеет статические методы. Я использовал его в моем методе конструктора, подобном этому;

IService.ProductService.GetMyProducts(); 

В Autofac я не нашел ничего подобного выше. Пожалуйста, помогите мне. Я не хочу использовать много интерфейсов в моем конструкторе.

private IGeneralRepository generalRep; 
     private IDenemeRepository denemeRep; 
     private IGokberkRepository GokberkRep; 

     public HomeController(IDenemeRepository dr,IGokberkRepository gr, IGeneralRepository ger) 
     { 
      generalRep = ger; 
      denemeRep = dr; 
      GokberkRep = gr; 
     } 
+1

В Autofac земли, вы используете много интерфейсов в конструкторе. Это правильный способ сделать это. Когда вы начинаете слишком много, вы понимаете, что ваш класс слишком велик. – Brannon

+0

В соответствии с вашим примером вы использовали ** образец Locator **. Существует много критики вокруг (см. [Этот поток, например] (http://stackoverflow.com/questions/22795459/is-servicelocator-anti-pattern)). Я лично избегаю ServiceLocator, потому что службы должны быть очищены после каждого модульного теста, что часто становится настоящей головной болью. Я бы предложил вам вместо этого использовать инсталляцию конструктора. –

ответ

1

Я могу придумать два способа уменьшить количество введенных услуг в вашем конструкторе.

Первого, в Autofac вы можете иметь один параметр типа IComponentContext, и когда ваша служба будет решена из экземпляра контейнера, IComponentContext зависимости автоматически разрешена к экземпляру контейнера. После этого вы можете решить остальную часть ваших зависимостей от него:

// constructor of your component 
public MyComponent(IComponentContext components) 
{ 
    _serviceA = components.Resolve<IServiceA>(); 
    _serviceB = components.Resolve<IServiceB>(); 
} 

Кстати, в замке Виндзор вы должны были явно зарегистрировать экземпляр контейнера для того, чтобы вышеупомянутый метод работы.

Второй способ создает одну «композитную» услугу, которая содержит все (или наиболее распространенные) услуги, которые необходимы приложению. Затем вводит эту услугу и получить все остальные от него:

// composite service - implement this interface as shown below 
public interface ICommonServices 
{ 
    IServiceA ServiceA { get; } 
    IServiceB ServiceB { get; } 
} 

Композитных реализации сервиса:

// a class that implements ICommonServices interface 
public class CommonServices : ICommonServices 
{ 
    public CommonServices(IServiceA serviceA, IServiceB serviceB) 
    { 
     this.ServiceA = serviceA; 
     this.ServiceB = serviceB; 
    } 

    public IServiceA ServiceA { get; private set; } 
    public IServiceB ServiceB { get; private set; } 
} 

Обратите внимание, что вы должны зарегистрировать составные услуги и внутренние службы в контейнере.

Теперь вы можете иметь только один параметр в конструкторе:

public MyComponent(ICommonServices services) 
{ 
    _services = services; 
} 

Используя внутренние услуги:

public void SomeMethod() 
{ 
    _services.ServiceA.DoSomething(); 
} 
+0

Хорошие примеры (+1). Хотя это может забрать некоторые из производительности, и AutoFac не рекомендует использовать его, если только вам не нужно это сделать, также можно сделать инъекцию свойств. Используя пример by @ felix-b, вы можете изменить реализацию CommonServices и удалить конструктор и сделать свойства setter общедоступными (возможно, внутренние работы тоже?). Вам просто нужно зарегистрировать свою реализацию (ы), которая разрешена введением свойств. Тогда вам вообще не нужно беспокоиться о конструкторе. – Igor

+0

Я попробовал второй способ, и внутренние интерфейсы хотят реализации. А именно IGenelralService имеет два внутренних интерфейса: IGokberk и IDeneme. Но IGokberk и IDeneme хотят реализовать свои собственные свойства самостоятельно. – MehmetF

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