Представьте, что у вас есть веб-сайт, в котором каждый пользователь может помещать код в поле, а затем нажмите «поиск», чтобы найти информацию о продукте. Код будет соответствовать шаблону: SHOPNAME-PROGRESSIVENUMBER
, например: EVERYDAYSHOES-002
, или NEWGAMES-005
.Как правильно управлять этой ситуацией с впрыском зависимостей
Когда пользователь нажмет кнопку «Поиск», мой код:
- Идентифицировать В магазине
- Получить строку подключения для подключения к БД, которая отличается для каждого магазина
- 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
}
}
Мои вопросы:
- Хорошо или плохо (и почему) делать Регистрация - разрешать при каждом нажатии на мою кнопку?
- Если это плохо, как я могу реорганизовать это, чтобы сделать его правильным по отношению к шаблону DI?
Что касается второго вопроса, то, что я подумал:
Просто позвоните Resolve перекрывая
connectionString
на каждой кнопке мышиСопоставить все возможные
SQLProductInformationsProvider
, кэшировать их в словаре и использовать необходимое одинУдалить
connectionString
от конструктора и разместить его по методуSetConnectionString(string connectionString)
, но в этом случае мне больше придется больше беспокоиться о безопасности потоков.
Все эти три идеи не удовлетворяют меня, они дают мне ощущение, что я что-то не понял. Что мне не хватает/как я могу изменить свою точку зрения?
Использование контейнера в первый регистр конкретных типов, а затем решить в следующей строке не имеет смысла. Какое значение здесь вводит контейнер против вызова 'new' на обоих типах? –
Как вы проходите '_shopsConnectionStringsMap'? через конструктор? Можете ли вы показать, как выглядит конструктор сейчас? –