Настройка приложения ядра консоли ввода зависимостей - PullRequest
0 голосов
/ 29 октября 2019

Я пытаюсь использовать внедрение зависимостей для приложения .Net Core Console, используя встроенный DI.

У меня есть 2 следующих метода:

    private static void RegisterServices()
    {
        var collection = new ServiceCollection();

        //repositories
        collection.AddScoped<IAccountDataRepository, AccountDataRepository>();
        collection.AddScoped<IClientDataRepository, ClientDataRepository>();
        collection.AddScoped<IAddressDataRepository, AddressDataRepository>();
        collection.AddScoped<IClientAccountDataRepository, ClientAccountDataRepository>();
        //services
        collection.AddScoped<IAccountDataService, AccountDataService>();
        collection.AddScoped<IClientDataService, ClientDataService>();
        collection.AddScoped<IAddressDataService, AddressDataService>();
        collection.AddScoped<IClientAccountDataService, ClientAccountDataService>();

        _serviceProvider = collection.BuildServiceProvider();

    }

    private static void DisposeServices()
    {
        if (_serviceProvider == null)
        {
            return;
        }
        if (_serviceProvider is IDisposable)
        {
            ((IDisposable)_serviceProvider).Dispose();
        }
    }

Я могу заставить это работатьв методе main с помощью этого:

private static IServiceProvider _serviceProvider;
private static IClientDataRepository _clientDataRepository;



static void Main(string[] args)
{

    RegisterServices();

    _clientDataRepository = _serviceProvider.GetService<IClientDataRepository>();

Однако мне нужно внедрить репозиторий в службу и службу в main, но я не могу использовать следующее в классе обслуживания:

_clientDataRepository = _serviceProvider.GetService<IClientDataRepository>();

Вот сервис:

public class ClientDataService : IClientDataService
{
    private readonly ILogger _logger;
    private readonly IClientDataRepository _clientDataRepository;

    public ClientDataService(ILogger logger, IClientDataRepository clientDataRepository)
    {
        _logger = logger;
        _clientDataRepository = clientDataRepository;
    }

Если я использую

_clientDataRepository = _serviceProvider.GetService<IClientDataRepository>();

выдаст ошибку

1 Ответ

1 голос
/ 29 октября 2019

Просто разрешите службу, и поставщик службы добавит хранилище в службу при построении графа объектов запрошенного объекта

На основе предоставленного ClientDataService вам также необходимо убедиться, что все зависимостизарегистрированы в коллекции сервисов.

Как показано на текущий момент, ClientDataService также зависит от ILogger, который, по-видимому, не зарегистрирован в коллекции услуг.

services.AddLogging();

В следующем примере используется изначально предоставленный код и рефакторинг для запуска основного с использованием внедрения зависимостей.

public class Program
    private readoonly IClientDataService service;

    public Program(IClientDataService service) {
        this.service = service;
    }

    public void SomeMethod() {
        //...
    }

    //entry
    public static void Main(string[] args) {
        IServiceProvider serviceProvider = RegisterServices();

        Program program = serviceProvider.GetService<Program>();

        program.SomeMethod();

        DisposeServices(serviceProvider);
    }

    //Support
    private static IServiceProvider RegisterServices() {
        var services = new ServiceCollection();

        //repositories
        services.AddScoped<IAccountDataRepository, AccountDataRepository>();
        services.AddScoped<IClientDataRepository, ClientDataRepository>();
        services.AddScoped<IAddressDataRepository, AddressDataRepository>();
        services.AddScoped<IClientAccountDataRepository, ClientAccountDataRepository>();
        //services
        services.AddScoped<IAccountDataService, AccountDataService>();
        services.AddScoped<IClientDataService, ClientDataService>();
        services.AddScoped<IAddressDataService, AddressDataService>();
        services.AddScoped<IClientAccountDataService, ClientAccountDataService>();
        services.AddLogging(); //<-- LOGGING
        //main
        services.AddScoped<Program>(); //<-- NOTE THIS

        return services.BuildServiceProvider();
    }

    private static void DisposeServices(IServiceProvider serviceProvider) {
        if (serviceProvider == null) {
            return;
        }
        if (serviceProvider is IDisposable sp) {
            sp.Dispose();
        }
    }
}
...