Как настроить Action <T>с внедрением зависимости - PullRequest
1 голос
/ 05 марта 2020

Я пытаюсь узнать, как работают Action<T> и Func<T>, для этого я создал базовый класс, который требует Action<AppConfiguration> в своем конструкторе среди других зависимостей:

public abstract class GenericOracleTDRRepository<T> : IGenericTDRRepository<T>
{
        protected GenericOracleTDRRepository(ILogger<GenericOracleTDRRepository<T>> logger,
                                             Action<AppConfiguration> configuration,
                                             IUpdateSqlStringGenerator<T> generator)
        {
            if (configuration is null)
            {
                throw new ArgumentNullException(nameof(configuration));
            }

            Logger = logger ?? throw new ArgumentNullException(nameof(logger));
            configuration(AppSettings);
            _generator = generator ?? throw new ArgumentNullException(nameof(generator));
        }

      public AppConfiguration AppSettings { get; private set; } = new AppConfiguration();
}



public class RmesgOracleReposityory : GenericOracleTDRRepository<RMesg>, IGenericTDRRepository<RMesg>
{
    public RmesgOracleReposityory(ILogger<RmesgOracleReposityory> logger,
                                  Action<AppConfiguration> appSettings,
                                  IUpdateSqlStringGenerator<RMesg> generator) : base(logger, appSettings, generator)
    {
        Logger = logger;
    }

    public new ILogger<RmesgOracleReposityory> Logger { get; }
}

Я настраиваю его в моем DI-контейнере:

services.AddScoped<IGenericTDRRepository<RMesg>, RmesgOracleReposityory>();
services.AddTransient<IUpdateSqlStringGenerator<RMesg>, UpdateSqlStringGenerator<RMesg>>();

Я не уверен, где и как мне передать действительный Action<AppConfiguration> для этого объекта?

1 Ответ

2 голосов
/ 05 марта 2020

Вам нужно определить Action<AppConfiguration> для использования где-нибудь.

Если вы, например, определите его в классе Startup, вы можете использовать перегрузку AddScoped, которая принимает IServiceProvider, чтобы разрешить другие зависимости и внедрить его следующим образом:

void TheAction(AppConfiguration appConfiguration) { }

services.AddScoped<IGenericTDRRepository<RMesg>, RmesgOracleReposityory>(serviceProvider =>
{
    var logger = serviceProvider.GetRequiredService<ILogger<RmesgOracleReposityory>>();
    var generator = serviceProvider.GetRequiredService<IUpdateSqlStringGenerator<RMesg>>();
    return new RmesgOracleReposityory(logger, TheAction, generator);
});

Вы также можете определить его в классе RmesgOracleReposityory и передать его конструктору базового класса:

public class RmesgOracleReposityory : GenericOracleTDRRepository<RMesg>, IGenericTDRRepository<RMesg>
{
    public RmesgOracleReposityory(ILogger<RmesgOracleReposityory> logger,
                                  IUpdateSqlStringGenerator<RMesg> generator) 
        : base(logger, TheAction, generator)
    {
        Logger = logger;
    }

    private void TheAction(AppConfiguration appConfiguration) { }

    public new ILogger<RmesgOracleReposityory> Logger { get; }
}

Action<T> просто инкапсулирует метод void, который принимает один параметр типа T.

...