Как создать класс без параметра конструктора, который имеет внедрение зависимости - PullRequest
0 голосов
/ 26 сентября 2018

Я добавил инъекции зависимостей в проект.Но когда я создаю экземпляр с помощью ключевого слова new , внедрение зависимостей не работает.

public class MyClass
{
    ILoginTokenKeyApi _loginTokenKeyApi;

    public MyClass(ILoginTokenKeyApi loginTokenKeyApi)
    {
        _loginTokenKeyApi = loginTokenKeyApi;
    }

    ...
}

Когда я пытаюсь создать экземпляр MyClass, онхочет, чтобы параметр был построен естественным образом.

Точно так же:

MyClass mc = new MyClass(); // ERROR, it wants a parameter (but it is what i want)

Мне нужно сделать:

MyClass mc = new MyClass(new LoginTokenKeyClass()); // this is not a good code for me

Как создать экземпляр MyClass без параметрапотому что в него вводится зависимость.

Ответы [ 3 ]

0 голосов
/ 26 сентября 2018

Как уже упоминалось в комментариях, неясно, чего вы пытаетесь достичь, но для того, чтобы сделать DI в .Net Core, вам нужно создать интерфейс IMyClass, а затем позволить вашему классу реализовать этот интерфейс,

public interface IMyClass {
   void SampleMethod();
}

public class MyClass : IMyClass
{
    ILoginTokenKeyApi _loginTokenKeyApi;

    public MyClass(ILoginTokenKeyApi loginTokenKeyApi)
    {
        _loginTokenKeyApi = loginTokenKeyApi;
    }

    public void SampleMethod()
    {
        // method logic goes here...
        var xx = _loginTokenKeyApi.WhatEver;
    }
}

затем зарегистрируйте ILoginTokenProvider и IMyClass в файле startup.cs

services.AddTransient<ILoginTokenProvider, LoginTokenProvider>();
services.AddTransient<IMyClass, MyClass>();

и, наконец, добавьте IMyClass, где вам это необходимо:

public class IndexModel : PageModel {

    private readonly IMyClass _myClass;

    public IndexModel(IMyClass myClass)
    {
        _myClass = myClass;
    }

    public void OnGet()
    {
       _myClass.SampleMethod();
    }
}

btw, также можно зарегистрировать и ввести MyClassбез реализации интерфейса IMyClass, но я предпочитаю следовать основным принципам программирования:)

0 голосов
/ 26 сентября 2018

Но когда я создаю экземпляр с помощью ключевого слова new, внедрение зависимостей не работает.

Это принципиально, как работает внедрение зависимостей.

С зависимостямиинъекция, вы просто не должны new новые объекты.В этом весь смысл внедрения зависимости и инверсии управления .Вместо того, чтобы создавать объекты и управлять зависимостями этих объектов, вы в зависимости от структуры даете вам зависимости , которые вам нужны, не заботясь о том, откуда они на самом деле и как они построены правильно.Таким образом, вы перекладываете ответственность за создание объекта на вызывающего.

Если вам нужно создать объект, имеющий зависимость, то это явный признак того, что вы делаете это неправильно.Распространенная причина этого заключается в том, что вы хотите создать объект для управления его временем жизни или потому, что на самом деле это объект данных, который просто имеет некоторые операции, для работы которых требуются другие зависимости (например, объект, который имеет «сохранить»Метод).В первом случае вы просто так не делаете.Вы просто зависите от этого и позволяете фреймворку управлять временем жизни;если он имеет неправильное время жизни, вам следует перенастроить его с контейнером DI.

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

Например, в ASP.NET Core Identity у вас естьUser объект, который является просто нормальной сущностью без какой-либо логики.Например, чтобы добавить роли пользователя или изменить пароль, вы полагаетесь на менеджера пользователей, которого вы можете ввести.Таким образом, сам объект User не имеет каких-либо зависимостей.

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

0 голосов
/ 26 сентября 2018

Существует два типа внедрения зависимостей.

  1. Внедрение в конструктор - которое вам не нужно
  2. Внедрение свойства - в этом - вы открываете свойство Public Get / Set объекта Object, который выхочу быть введенным.А затем в вашем конфигурационном файле DI (например, spring.net) вы можете назначать значения.

Еще один способ, которым вы можете сделать DepInjection, это то, что в конструкторе без параметров - вы можете получить объект с помощью ключа /Название.Как в Spring.Net, мы бы сделали:

var UtilityObject = Spring.ContextRegistry.GetContext().GetObject("MyUtilObject") as TheUtilityClass;
...