Реализация универсальной фабрики услуг или провайдера в Autofac - PullRequest
2 голосов
/ 22 сентября 2010

У меня есть интерфейс, например ISomeService.ISomeService предоставляет общую услугу, но реализации могут отличаться.Как таковые, они будут иметь разные зависимости.

Рассмотрим:

interface ISomeService
{
     void DoSomething();
}

class SomeServiceA : ISomeService
{
     public SomeServiceA(DependencyOne one, DependencyTwo two)
     {
     }


     public void DoSomething()
     {
     }
}

class SomeServiceB : ISomeService
{
     public SomeServiceB(DependencyThree three)
     {
     }

     public void DoSomething()
     {
     }
}

Теперь реальность такова, что я не могу просто добавить зависимость к ISomeService в мой контроллер и покончить с этим.Мне нужно будет выбрать реализацию IService на основе того, что говорит мне пользователь, и мне, возможно, придется создать несколько копий выбранной ими службы.

Возможно, у меня будет класс, который позволит мне разрешитьМне нужен экземпляр ISomeService, по типу:

class SomeServiceProvider
{
    public T Get<T>()
        where T : ISomeService
    {
          // uh oh, this is starting to have a bad smell... do I call the container? that's no good
    }

}

Так что я мог бы

class SomeController
{
     SomeServiceProvider ServiceProvider { get; set; }

     public SomeController(ServiceProvider provider)
     { ServiceProvider = provider; }

     public void SomeAction(string serviceName)
     {
          ISomeService someService;
          if (serviceName.Equals('SomeServiceA')) someService = ServiceProvider.Get<SomeServiceA>();
          else someService = ServiceProvider.Get<SomeServiceB>();
          someService.DoSomething();
     }

}

Кажется, что фабрика делегатов Autofac здесь не подходит, и я не уверен, чтоделать иначе (кроме использования сервисного локатора).Любые рекомендации?

1 Ответ

2 голосов
/ 22 сентября 2010

Это то, что вам нужно? Типы сервисов, имена и ключи

Сервисы могут быть дополнительно идентифицированы по имени сервиса.Используя эту технику, метод регистрации Named () заменяет As ().

builder.Register<OnlineState>().Named<IDeviceState>("online");

Для извлечения именованной службы используется метод ResolveNamed ():

var r = container.ResolveNamed<IDeviceState>("online");
...