Использование фабричного шаблона с внедрением зависимостей ядра ASP.NET - PullRequest
0 голосов
/ 10 января 2019

Мне нужно внедрение зависимостей ASP.Net Core для передачи некоторых параметров в конструктор моего класса GlobalRepository, который реализует интерфейс ICardPaymentRepository.

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

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

Мой стартап выглядит следующим образом:

public class Startup
{
    public IConfiguration _configuration { get; }
    public IHostingEnvironment _environment { get; }

    public Startup(IConfiguration configuration, IHostingEnvironment environment)
    {
        _configuration = configuration;
        _environment = environment;
    }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddScoped<IDbRepository, DbRepository>();
        var connection = _configuration.GetConnectionString("DbConnection");
        services.Configure<ConnectionStrings>(_configuration.GetSection("ConnectionStrings"));
        services.AddDbContext<DbContext>(options => options.UseSqlServer(connection));
        services.AddScoped<ICardPaymentRepository, GlobalRepository>();
        ...
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IRFDbRepository rFDbRepository)
    {
     ...
    }
}

Конструктор GlobalRepository выглядит следующим образом:

public GlobalRepository(string mode, string apiKey)
{
}

Как теперь передать режим из конфигурации и apiKey из DbRepository в конструктор из автозагрузки?

Ответы [ 2 ]

0 голосов
/ 15 мая 2019

Вы можете также проверить эти ссылки ...

https://github.com/Microsoft/AspNetCoreInjection.TypedFactories

https://espressocoder.com/2018/10/08/injecting-a-factory-service-in-asp-net-core/

Что касается последней ссылки, код в основном:

public class Factory<T> : IFactory<T>
{
    private readonly Func<T> _initFunc;

    public Factory(Func<T> initFunc)
    {
        _initFunc = initFunc;
    }

    public T Create()
    {
        return _initFunc();
    }
}

public static class ServiceCollectionExtensions
{
    public static void AddFactory<TService, TImplementation>(this IServiceCollection services) 
    where TService : class
    where TImplementation : class, TService
    {
        services.AddTransient<TService, TImplementation>();
        services.AddSingleton<Func<TService>>(x => () => x.GetService<TService>());
        services.AddSingleton<IFactory<TService>, Factory<TService>>();
    }
}

Я думаю, что типизированные фабрики в замке Виндзора утилизируют все, что они создали, когда сами их утилизируют (что не всегда может быть лучшей идеей), с этими ссылками, которые вам, вероятно, придется рассмотреть, если вы все еще ожидаете такого поведения. Когда я пересмотрел вопрос о том, почему мне нужна фабрика, я просто создал новую фабричную упаковку, например:

public class DefaultFooFactory: IFooFactory{
  public IFoo create(){return new DefaultFoo();}
}
0 голосов
/ 10 января 2019

Использовать фабричную перегрузку делегата при регистрации репозитория

//...

var mode = "get value from config";

services.AddScoped<ICardPaymentRepository, GlobalRepository>(sp => {        
    var repo = sp.GetService<IDbRepository>();
    var apiKey = repo.GetApiKeyMethodHere();

    return new GlobalRepository(mode, apiKey);
});

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