2016-09-03 4 views
1

Представьте, что у вас есть веб-сайт, в котором каждый пользователь может помещать код в поле, а затем нажмите «поиск», чтобы найти информацию о продукте. Код будет соответствовать шаблону: SHOPNAME-PROGRESSIVENUMBER, например: EVERYDAYSHOES-002, или NEWGAMES-005.Как правильно управлять этой ситуацией с впрыском зависимостей

Когда пользователь нажмет кнопку «Поиск», мой код:

  1. Идентифицировать В магазине
  2. Получить строку подключения для подключения к БД, которая отличается для каждого магазина
  3. Invoke запрос к этой БД с этой строкой соединения.

Первое, что пришло мне на ум, чтобы достичь этого, было закодировать что-то вроде:

public interface IProductInformationsProvider 
{ 
    string GetProductName(int productCode); 
} 

public class SQLProductInformationsProvider : IProductInformationsProvider 
{ 
    ... 

    public SQLProductInformationsProvider(
     string connectionString, 
     ILogService logService) 
    { 
     ... 
    } 

    public string GetProductName(int productCode) 
    { 
     ... 
    } 
} 

Чтобы получить istance из IProductInformationsProvider Я хотел бы использовать DI контейнер и сделать что-то вроде:

...

public void SearchButtonHandler(Dictionary<string, string> shopsConnectionStringsMap) 
{ 
    using (var container = new WindsorContainer()) 
    { 
     container.Register(
      Component.For<ILogService>() 
      .ImplementedBy<ConsoleLogService>()); 

     container.Register(
      Component.For<IProductInformationsProvider>() 
      .ImplementedBy<SQLProductInformationsProvider>() 
      .DependsOn(
       Dependency.OnValue("connectionString", shopsConnectionStringsMap[parsedShopName])); 

     var productInformationsProvider = container.Resolve<IProductInformationsProvider>(); 
     var productName = productInformationsProvider.GetProductName(theCode); 
     // Do something with productName 
    } 
} 

Мои вопросы:

  1. Хорошо или плохо (и почему) делать Регистрация - разрешать при каждом нажатии на мою кнопку?
  2. Если это плохо, как я могу реорганизовать это, чтобы сделать его правильным по отношению к шаблону DI?

Что касается второго вопроса, то, что я подумал:

  1. Просто позвоните Resolve перекрывая connectionString на каждой кнопке мыши

  2. Сопоставить все возможные SQLProductInformationsProvider, кэшировать их в словаре и использовать необходимое один

  3. Удалить connectionString от конструктора и разместить его по методу SetConnectionString(string connectionString), но в этом случае мне больше придется больше беспокоиться о безопасности потоков.

Все эти три идеи не удовлетворяют меня, они дают мне ощущение, что я что-то не понял. Что мне не хватает/как я могу изменить свою точку зрения?

+0

Использование контейнера в первый регистр конкретных типов, а затем решить в следующей строке не имеет смысла. Какое значение здесь вводит контейнер против вызова 'new' на обоих типах? –

+0

Как вы проходите '_shopsConnectionStringsMap'? через конструктор? Можете ли вы показать, как выглядит конструктор сейчас? –

ответ

2

Решение Я думал это:

public interface IProductInformationsProvider 
{ 
    string GetProductName(int productCode); 
} 

public interface IConnectionStringProvider 
{ 
    string GetConnectionString(string shopName); 
} 

public class SQLProductInformationsProvider : IProductInformationsProvider 
{ 
    ... 

    public SQLProductInformationsProvider(
     IConnectionStringProvider connectionStringProvider, 
     ILogService logService) 
    { 
     ... 
    } 

    public string GetProductName(string shopName, int productCode) 
    { 
     string connectionString = connectionStringProvider.GetConnectionString(shopName); 
     ... 
    } 
} 

public void SearchButtonHandler(string shopName, int Code) 
{ 
    // _productInformationsProvider already resolved 
    var productName = _productInformationsProvider.GetProductName(shopName, Code); 
    // Do something with productName 
}