У меня есть две разные реализации для одного интерфейса, которые мне нужно зарегистрировать во внедрении зависимостей, и мне нужно условно проверить, какую реализацию создавать в данный момент.
Я использовал шаблон фабрики и делегат фабрики, и я просто хочу знать, есть ли лучший способ добиться этого.
Я буду использовать простые объекты, чтобы упростить задачу
IExampleService
internal interface IExampleService
{
public ExampleMode Mode { get; }
void Show();
}
internal enum ExampleMode
{
ExampleA,
ExampleB
}
ExampleAService
public ExampleMode Mode => ExampleMode.ExampleA;
public ExampleAService()
{
Console.WriteLine("Creating Example A");
}
public void Dispose()
{
Console.WriteLine("Disposing Example A");
}
public void Show()
{
Console.WriteLine("Example A Show");
}
ExampleBService
public ExampleMode Mode => ExampleMode.ExampleB;
public ExampleBService()
{
Console.WriteLine("Creating Example B");
}
public void Dispose()
{
Console.WriteLine("Disposing Example B");
}
public void Show()
{
Console.WriteLine("Example B Show");
}
Каков подходящий способ добиться выбора условной реализации при внедрении зависимостей.
Я использовал две разные реализации шаблона фабрики, первая использует Ienumerable, поэтому службы создаются DI и соответствуют назначенному зарегистрированному сроку службы, но я хочу избежать накладных расходов на создание экземпляров всех реализаций только для выбора одной.
Чтобы решить эту проблему, я использовал другой вариант фабрики, где я вручную создаю экземпляр требуемой службы но теперь мне нужно убедиться, что я удаляю этот объект вручную и эти службы больше не соответствуют зарегистрированному сроку службы службы.
ExampleServiceFactory
internal class ExampleServiceFactory : IExampleServiceFactory
{
private readonly IEnumerable exampleServices;
public ExampleServiceFactory(IEnumerable exampleServices)
{
this.exampleServices = exampleServices;
}
public IExampleService GetExampleService(ExampleMode mode)
{
//Using DI to inject Ienumerable of services
return exampleServices.FirstOrDefault(x => x.Mode == mode);
//Manually instantiate Services
//return mode switch
//{
// ExampleMode.ExampleA => new ExampleAService(),
// ExampleMode.ExampleB => new ExampleBService(),
// _ => throw new NotSupportedException(),
//};
}
}
и внедрение IServiceProvider в фабрику имело для меня смысл, но, похоже, это антишаблон
Еще один вариант локатора сервисов, которого следует избегать, — это внедрение фабрики, которая разрешает зависимости во время выполнения. Обе эти практики сочетают в себе стратегии инверсии управления.
в настоящее время я использую фабричный делегат для условного создания экземпляра требуемой реализации и передачи ее в оболочку, которую я могу свободно внедрять на другие страницы, в контроллер и т. д.
Program.cs
builder.Services.AddKeyedSingleton("ExampleA");
builder.Services.AddKeyedTransient("ExampleB");
builder.Services.AddTransient();
builder.Services.AddTransient();
//var exampleMode = ConfigurationManager.AppSettings["Device"];
builder.Services.AddTransient((ctx) =>
{
var configProvider = ctx.GetRequiredService();
var exampleMode = configProvider.GetExampleMode();
var service = exampleMode switch
{
ExampleMode.ExampleA => ctx.GetRequiredKeyedService("ExampleA"),
ExampleMode.ExampleB => ctx.GetRequiredKeyedService("ExampleB"),
_ => throw new InvalidOperationException()
};
return new GenericExampleService(service);
});
Подробнее здесь: https://stackoverflow.com/questions/782 ... -injection
Динамический выбор реализации при внедрении зависимостей .NET ⇐ C#
Место общения программистов C#
-
Anonymous
1711978570
Anonymous
У меня есть две разные реализации для одного интерфейса, которые мне нужно зарегистрировать во внедрении зависимостей, и мне нужно условно проверить, какую реализацию создавать в данный момент.
Я использовал шаблон фабрики и делегат фабрики, и я просто хочу знать, есть ли лучший способ добиться этого.
Я буду использовать простые объекты, чтобы упростить задачу
[b]IExampleService
internal interface IExampleService
{
public ExampleMode Mode { get; }
void Show();
}
internal enum ExampleMode
{
ExampleA,
ExampleB
}
ExampleAService[/b]
public ExampleMode Mode => ExampleMode.ExampleA;
public ExampleAService()
{
Console.WriteLine("Creating Example A");
}
public void Dispose()
{
Console.WriteLine("Disposing Example A");
}
public void Show()
{
Console.WriteLine("Example A Show");
}
[b]ExampleBService[/b]
public ExampleMode Mode => ExampleMode.ExampleB;
public ExampleBService()
{
Console.WriteLine("Creating Example B");
}
public void Dispose()
{
Console.WriteLine("Disposing Example B");
}
public void Show()
{
Console.WriteLine("Example B Show");
}
Каков подходящий способ добиться выбора условной реализации при внедрении зависимостей.
Я использовал две разные реализации шаблона фабрики, первая использует Ienumerable, поэтому службы создаются DI и соответствуют назначенному зарегистрированному сроку службы, но я хочу избежать накладных расходов на создание экземпляров всех реализаций только для выбора одной.
Чтобы решить эту проблему, я использовал другой вариант фабрики, где я вручную создаю экземпляр требуемой службы но теперь мне нужно убедиться, что я удаляю этот объект вручную и эти службы больше не соответствуют зарегистрированному сроку службы службы.
[b]ExampleServiceFactory[/b]
internal class ExampleServiceFactory : IExampleServiceFactory
{
private readonly IEnumerable exampleServices;
public ExampleServiceFactory(IEnumerable exampleServices)
{
this.exampleServices = exampleServices;
}
public IExampleService GetExampleService(ExampleMode mode)
{
//Using DI to inject Ienumerable of services
return exampleServices.FirstOrDefault(x => x.Mode == mode);
//Manually instantiate Services
//return mode switch
//{
// ExampleMode.ExampleA => new ExampleAService(),
// ExampleMode.ExampleB => new ExampleBService(),
// _ => throw new NotSupportedException(),
//};
}
}
и внедрение IServiceProvider в фабрику имело для меня смысл, но, похоже, это антишаблон
Еще один вариант локатора сервисов, которого следует избегать, — это внедрение фабрики, которая разрешает зависимости во время выполнения. Обе эти практики сочетают в себе стратегии инверсии управления.
в настоящее время я использую фабричный делегат для условного создания экземпляра требуемой реализации и передачи ее в оболочку, которую я могу свободно внедрять на другие страницы, в контроллер и т. д.
[b]Program.cs[/b]
builder.Services.AddKeyedSingleton("ExampleA");
builder.Services.AddKeyedTransient("ExampleB");
builder.Services.AddTransient();
builder.Services.AddTransient();
//var exampleMode = ConfigurationManager.AppSettings["Device"];
builder.Services.AddTransient((ctx) =>
{
var configProvider = ctx.GetRequiredService();
var exampleMode = configProvider.GetExampleMode();
var service = exampleMode switch
{
ExampleMode.ExampleA => ctx.GetRequiredKeyedService("ExampleA"),
ExampleMode.ExampleB => ctx.GetRequiredKeyedService("ExampleB"),
_ => throw new InvalidOperationException()
};
return new GenericExampleService(service);
});
Подробнее здесь: [url]https://stackoverflow.com/questions/78253323/dynamic-implementation-selection-in-net-dependency-injection[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия