Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Передайте параметр при инициализации внедрения зависимостей в ядре ASP.NET

Автор вопроса: Rasmus HansenОтветов: 1

У меня есть простой класс, который выглядит так:

public class TestClass1
{
    private string testString = "Should be set by DI";

    public TestClass1(string testString)
    {
        this.testString = testString;
    }
    public string GetData()
    {
        return testString + DateTime.Now;
    }
}

Я хочу внедрить его с помощью встроенного DI в простое основное веб-приложение ASP.NET, но с параметром testString, установленным при инициализации внедрения зависимостей.

Я попытался установить следующее в startup.cs, но во время выполнения это не работает, потому что TestClass1 не имеет конструктора без параметров:

services.AddScoped(provider => new TestClass1("Success!"));
  • Ваш вопрос не имеет смысла; код, который вы разместили, будет работать нормально. Возможно, вам не хватает какой-то важной информации в вашем вопросе, но я не могу определить, что вам не хватает. Опубликуйте полученные сведения об исключении (тип исключения, сообщение, трассировка стека и сведения о внутреннем исключении). Steven 13.07.2016
  • Вы действительно вводите этот класс, пытаетесь ли вы инициализировать его "новым", как в new TestClass()? ДИ так не работает Tseng 13.07.2016
  • Не могли бы вы опубликовать свой метод ConfigureServices? adem caglin 13.07.2016
  • @Tseng: конечно, иногда вам нужно напрямую зарегистрировать экземпляр типа. Итак, это распространенный сценарий. Как уже написал Стивен, это должно работать так. Juergen Gutsch 13.07.2016
  • @JuergenGutsch: Нет, вы не используете ключевое слово new при получении экземпляра. Вы всегда вводите его через конструктор. DI - это не какая-то магия компилятора, это просто CLR/OOP с небольшим количеством отражений или ExpressionTrees. Я подозреваю, что он делает new TestClass() в своем коде (обратите внимание на новое ключевое слово и отсутствие параметра). ДИ работает не так. Скорее вы передаете его через конструктор, например public MyService(TestClass injectedTestCass) Tseng 13.07.2016
  • Как упоминал @Tseng, я не должен использовать ключевое слово new, потому что DI должен обрабатывать создание экземпляра класса. Но я понятия не имею, как написать строку services.AddScoped с параметрами, если я не использую ключевое слово new Rasmus Hansen 13.07.2016

dependency-injection

Ответы

Ответ 1 · рейтинг 1 · Tseng

Я подозреваю, что вы просто пропустили важнейшую часть кода, и ваше использование DI просто неправильно, а не регистрация.

public class MyController
{
    private readonly MyClass myClass;

    public MyController()
    {
        // This doesn't work and do not involve DI at all
        // It will fail because MyClass has no parameterles constructor
        this.myClass = new MyClass();
    }
}

Вышеприведенное не сработает, потому что DI не является магией компилятора, которая позволяет вам волшебным образом внедрять зависимости при вызове new для типа.

public class MyController
{
    private readonly MyClass myClass;

    public MyController(MyClass myClass)
    {
        // This should work, because the IoC/DI Container creates the instance
        // and pass it into the controller
        this.myClass = myClass;
    }
}

Когда вы используете DI/IoC, вы позволяете конструктору генерировать и создавать экземпляры объектов, поэтому вы никогда не вызываете new в своих классах обслуживания. Просто скажите в конструкторе, что вам нужен экземпляр какого-то типа или его интерфейс.

Изменить:

Раньше это работало в предыдущих версиях (бета-версиях) ASP.NET Core. Должен по-прежнему работать, но ограничен параметрами:

public class MyController
{
    public IActionResult Index([FromServices]MyClass myClass)
    {
    }
}

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы