Во всех случаях вариант 2 - плохой.
- Шаблон локатора службы широко считается антипаттерном. Это может решить имеющуюся проблему, но в дальнейшем создает множество других проблем.
- Вы позволяете своему потребителю решать, какой клиент использовать, что фактически сводит на нет идею позволить службе определять свою собственную зависимость с помощью конструктор.
- Magi c строки нежелательны. Если ваш потребитель все равно выбирает клиента, то для него нет смысла использовать какую-то строку magi c для выбора правильного клиента. Если позволить им передать самого клиента, значительно меньше вероятность ошибок, но тогда
Service
не полагается на структуру DI для клиентского объекта, что может нарушить цель вашей настройки.
ЕСЛИ выбор клиента выполняется динамически каждый раз при вызове GetData()
, тогда вариант 1 является допустимым подходом.
Хотя я бы предложил использовать более описательные имена, чем «client1 "и" client2 ", где это возможно.
IF выбор клиента - Dynami c, но остается фиксированным после запуска приложения, что означает, что все вызовы GetData()
в течение одного времени выполнения будут обрабатываться одним и тем же клиентом, тогда это лучше чтобы выбрать этого клиента при регистрации ваших зависимостей:
// Startup.cs
if( /* selection criteria */)
{
services.AddScoped<IClient, Client1>();
}
else
{
services.AddScoped<IClient, Client2>();
}
// Service.cs
public class Service
{
private readonly IClient client;
public Service(IClient client)
{
this.client = client;
}
public Data GetData(string something)
{
return this.client.GetData(something);
}
}
Хотя я бы предложил использовать более описательные имена, чем «client1» и «client2», где это возможно.
Обратите внимание, что ваш критерий выбора может быть какими бы они ни были, например, значение конфигурации приложения, значение базы данных, значение среды, тип компиляции (отладка / выпуск) ... Мир - это ваша устрица.
Также оцените, не лучше ли вам реализовать дополнительную абстракцию, которая может решить, на какого клиента перенаправлять (например, ClientFactory
или ClientRouter
). Это не всегда необходимо, но если ваши требования нетривиальны, абстракция может помочь упростить задачу.