2014-09-08 7 views
0

Я имею дело с одной проблемой. Представьте себе эту примерную ситуацию. У меня есть один модуль, например. UserModule с вложенным IUserRepository. IUserRepository может иметь больше реализаций, например. IUserRepositorySql и IUserRepositoryDefault.Зависимость впрыска - именованные зависимости

public class UserModule : IUserModule 
{ 
    private readonly IUserRepository userRepository; 

    public UserModule(IUserRepository userRepository) 
    { 
     if (userRepository == null) throw new ArgumentNullException("userRepository"); 
     this.userRepository = userRepository; 
    } 
} 

Я хотел бы определить, какая реализация IUserRepository будет использоваться в UserModule. Я хочу избежать шаблона Factory, который рассматривается как IoC antipattern в Marc Seeman book, и я хотел бы достичь этого только с конфигурацией контейнера.

Я использую LightInject и имеет что-то вроде named services, но его можно использовать только на верхнем уровне. Мне нужно что-то вроде этого:

var container = new ServiceContainer(); 

container.Register<IUserRepository, UserRepositorySql>("Sql"); 
container.Register<IUserRepository, UserRepositoryDefault>("Default"); 
container.Register<IUserModule, UserModule>(); 

var instance = container.GetInstance<IUserModule>("Sql"); 

Этого код должен возвращать экземпляр IUserModule с закачиваемым например UserRepositorySql, но, конечно, это не так.

У вас есть какая-то душа для этого в LightInject, пожалуйста?

Я нашел функцию annotation in Lightinject, где я могу впрыскивать некоторые свойства соответствующих типов, но мне это не так нравится.

Есть ли у вас опыт в некоторых других контейнерах IoC? Как вы/какая функция разрешает эту проблему?

+0

Я прочитал книгу Марка Семанна, но не могу вспомнить, что он назвал фабрику анти-узором. Можете ли вы ссылаться на страницы, где он это делает? – Steven

+0

Можете ли вы объяснить, почему вам действительно нужно это сделать? – Steven

+1

Я знаю, что Марк Seemann считает, что Service Locator является анти-шаблоном (http://blog.ploeh.dk/2010/02/03/ServiceLocatorisanAnti-Pattern/), так вот как я прочитал этот вопрос. – Astrotrain

ответ

1

Я должен был бы согласиться как с Стивеном, так и с Астротрейнером, но есть третий вариант.

В следующем примере используются параметры для правильной реализации интерфейса IUserRepository.

using LightInject; 

class Program 
{ 
    static void Main(string[] args) 
    { 
     var container = new ServiceContainer(); 
     container.Register<IUserRepository, UserRepositorySql>("Sql"); 
     container.Register<IUserRepository, UserRepositoryDefault>("Default"); 
     container.Register<string, IUserModule>(
      (factory, serviceName) => new UserModule(factory.GetInstance<IUserRepository>(serviceName))); 

     var userModuleWithSqlRepository = container.GetInstance<string, IUserModule>("Sql"); 
     var userModuleWithDefaultRepository = container.GetInstance<string, IUserModule>("Default"); 
    } 
} 

public interface IUserModule { } 

public class UserModule : IUserModule 
{ 
    public UserModule(IUserRepository repository) 
    { 
    } 
} 

public interface IUserRepository { } 

public class UserRepositorySql : IUserRepository { } 

public class UserRepositoryDefault : IUserRepository { } 
1

Я знаю, что Unity поддерживает с уточнением именованного экземпляром для использования при выполнении инъекции конструкторы с помощью ResolvedParameter класса (который работает только как ваша воображаемая конструкция):

container.Register<IUserModule, UserModule>(
    new InjectionConstructor(
     new ResolvedParameter<IUserModule>("Sql"))); 

Однако большинство структур DI также поддерживают фабричные методы, и приведенный выше пример также может быть записана в Unity как:

container.Register<IUserModule>(
    new InjectionFactory(cont => cont.Resolve<IUserModule>("Sql")); 

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

Я подозреваю, что последнее строительство вполне может быть возможно с вашей картой DI .

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