Получить зависимость при необходимости? - PullRequest
0 голосов
/ 04 марта 2020

Есть ли способ получить / получить зависимости только тогда, когда это необходимо?

public class DependentClass
{
    public DependentClass(IMandatoryDependency mandatoryDependency, IDependency1 dependency1, IDependency2 dependency2, IDependency3 dependency3)
    {
        // Assigned to class level property
    }

    public void MethodsOne()
    {
        mandatoryDependency.CallMandatoryMethod();
        dependency1.CallDependecy1Method();
    }

    public void MethodsTwo()
    {
        mandatoryDependency.CallMandatoryMethod();
        dependency2.CallDependecy2Method();
    }

    public void MethodsThree()
    {
        mandatoryDependency.CallMandatoryMethod();
        dependency3.CallDependecy3Method();
    }
}

Из приведенного выше фрагмента я хотел бы получить зависимость для отдельных методов, когда я нахожусь внутри самих методов. Как то так:

public class DependentClass
{
    public DependentClass(IMandatoryDependency mandatoryDependency)
    {
        // Assigned to class level property
    }

    public void MethodsOne()
    {
        mandatoryDependency.CallMandatoryMethod();
        DIContainer.GetDependency<IDependency1>().CallDependecy1Method();
    }

    public void MethodsTwo()
    {
        mandatoryDependency.CallMandatoryMethod();
        DIContainer.GetDependency<IDependency2>().CallDependecy2Method();
    }

    public void MethodsOne()
    {
        mandatoryDependency.CallMandatoryMethod();
        DIContainer.GetDependency<IDependency3>().CallDependecy3Method();
    }
}

Ответы [ 3 ]

3 голосов
/ 04 марта 2020

Предполагая, что вы используете контейнер IO C, вы можете внедрить экземпляр контейнера, который сам по себе, в конструктор, а затем использовать этот экземпляр, чтобы решить ваши службы плохо. Это плохая практика, возможно, вы ищете что-то как this

Другим хорошим вариантом было бы сделать необязательные зависимости объектами Lazy, просто используя класс Lazy, поэтому вы будете кодировать Lazy<IDependency1>

, используя Ленивый шаблон гарантирует, что объекты не будут созданы, если вы на самом деле не хотите к ним обращаться, вы можете прочитать больше об этом здесь

1 голос
/ 04 марта 2020

Вам необходимо зарегистрировать службы как Lazily в StartUp.cs.

services.AddTransient<IDependecy1, Dependecy1>();
services.AddTransient(serviceProvider => new Lazy<IDependecy1>(() => serviceProvider.GetRequiredService<IDependecy1>()));

Тогда в вашем Controller используйте зависимость как Lazy

public class DependentClass
{
    private readonly Lazy<IDependency1> _dependency1;
    public DependentClass(IMandatoryDependency mandatoryDependency, Lazy<IDependency1> dependency1)
    {
        // Assigned to class level property
        _dependency1 = dependency1;
    }

    public void MethodsOne()
    {
        mandatoryDependency.CallMandatoryMethod();
        _dependency1.Value.CallDependecy1Method();
    }
}

Если вы используете IDependency1 только в одном методе, поэтому вы можете разрешить зависимость, используя FromServices в . NET core вместо введения зависимости в конструкторе.

public void MethodsOne([FromServices] IDependency1 dependency1)
    {
        mandatoryDependency.CallMandatoryMethod();
        dependency1.CallDependecy1Method();
    }
0 голосов
/ 04 марта 2020

в asp. net ядре мы можем внедрить IServiceProvider в контроллер и самостоятельно разрешить зависимости во время выполнения, например:

private IServiceProvider _serviceProvider;
private IMandatoryDependency _mandatoryDependency;
public DependentClass(IMandatoryDependency mandatoryDependency,
                      IServiceProvider serviceProvider)
{
    _serviceProvider = serviceProvider;
    _mandatoryDependency = mandatoryDependency;
}

и в методе мы можем запросить у провайдера предоставить экземпляр конкретной зависимости, такой как:

public void MethodsOne()
{
    mandatoryDependency.CallMandatoryMethod();
    _serviceProvider.GetService(typeof(IDependency1)).CallDependecy1Method();
}

Но не рекомендуется вводить IServiceProvider, см .:

Почему бы не внедрить IServiceProvider вместо каждой отдельной зависимости?

Подробнее об услуге внедрения зависимостей, в частности, в ядре asp. net, можно узнать по следующему адресу:

https://andrewlock.net/new-in-asp-net-core-3-service-provider-validation/

http://www.binaryintellect.net/articles/17ee0ba2-99bb-47f0-ab18-f4fc32f476f8.aspx

Также ознакомьтесь с рекомендациями по внедрению зависимостей в asp. net core:

https://medium.com/volosoft/asp-net-core-dependency-injection-best-practices-tips-tricks-c6e9c67f9d96

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...