Matrimony Ответов: 0

Динамическая инъекция зависимостей в ASP.NET ядро MVC


В моем приложении есть один интерфейс и два подкласса.
В качестве служб были зарегистрированы два подкласса.
Мой вопрос заключается в том, как контролировать, какой из них получить, когда я их использую?

//HomeController.cs  
public class HomeController : Controller
    {
        public interface ITestDI
        {

        }

        public class TestDIClass1: ITestDI
        {
            public TestDIClass1()
            {
                    
            }
        }
        
        public class TestDIClass2 : ITestDI
        {
            public TestDIClass2()
            {

            }
        }

        ITestDI td;

        public HomeController(ITestDI _td)
        {
            this.td = _td; // how to control which ITestDI implementation will injected with constructor injection? With the configuration below, always get TestDIClass2.
        }

        public IActionResult Index()
        {
            return View();
        }
    } 

//Startup.cs
services.AddScoped<ITestDI, TestDIClass1>();
services.AddScoped<ITestDI, TestDIClass2>();// it seems like TestDIClass2 has overwrited the TestDIClass1.


Что я уже пробовал:

если при инициализации подкласса конструктору необходимо предоставить параметр param, как это сделать?

lw@zi

DI в ядре-это не то же самое, что правильные поставщики IoC. Это действительно простая и быстрая в использовании версия. Я могу придумать несколько способов, но для этого потребуется редизайн класса и, возможно, заводская реализация. Альтернативным вариантом может быть использование стороннего поставщика IoC по выбору, который будет иметь встроенную в него эту функцию.

Matrimony

Спасибо,lw@zi. я только что понял, что DI в core не так мощен, как другие поставщики IoC.
Не могли бы вы предоставить заводскую реализацию?

lw@zi

Вот несколько ссылок: https://dotnetliberty.com/index.php/2016/05/09/asp-net-core-factory-pattern-dependency-injection/ и https://joonasw.net/view/aspnet-core-di-deep-dive-да. Лично я предпочел бы использовать AutoFac вместо всего этого редизайна и тяжелой работы.

Matrimony

Это помогает, спасибо.

услуги.AddTransient<icontrolpanel>(serviceProvider =>
{
var context = serviceProvider.GetRequiredService<ihttpcontextaccessor>().HttpContext;
ВАР userHeader = контекст.Запрос.Заголовки["loggedInUser"];
если (строка.IsNullOrEmpty(userHeader)) возвращает новую панель GuestControlPanel();
if ("admin" == userHeader) return new AdminControlPanel();
возврат новой NormalUserControlPanel(userHeader);
});

0 Ответов