Как зарегистрировать сервисы в модуле Autoac, которые полагаются на значения конфигурации из внешнего файла - PullRequest
1 голос
/ 12 мая 2019

Я использую Autofac и dot net core для создания консольного приложения.

Одна из моих служб, которую я хочу зарегистрировать, - это служба API, которую я создал.Его конструктор принимает некоторые параметры, которые являются значениями, хранящимися в файле конфигурации, к которому я могу получить доступ через ConfigurationBuilder (зарегистрированный при запуске программы).

Как мне зарегистрировать сервисы, при этом у конструктора есть параметры, которые доступныв IConfigurationRoot?

Например, конструктор моего сервиса:

public DearInventoryApiService(ILogger<DearInventoryApiService> logger, string baseUrl, string accountId, string applicationKey)

Я регистрирую контейнер в моем Program.cs следующим образом:

    private static void RegisterServices()
    {
        var collection = new ServiceCollection();
        collection.AddLogging(configure => configure.AddConsole());

        //register the autofac container provider
        var containerBuilder = new ContainerBuilder();

        //register the default module
        containerBuilder.RegisterModule(new DefaultDependencyModule());
        containerBuilder.Populate(collection);
        var container = containerBuilder.Build();

        ServiceProvider = new AutofacServiceProvider(container);
    }

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

public class DefaultDependencyModule : Module
{
    protected override void Load(ContainerBuilder builder)
    {
        builder.Register(r => new DearInventoryApiService(r.Resolve<ILogger<DearInventoryApiService>>(), {base url here}, {account id here}, {application key here})).As<IDearInventoryService>();

    }
}

Моя проблема с вышесказанным заключается в том, что я не уверен, как получить значения конфигурации в модуль для регистрации?

Редактировать 1:

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

public class DefaultDependencyModule : Module
{
    private IConfigurationRoot ApplicationConfiguration;

    public DefaultDependencyModule(IConfigurationRoot applicationConfiguration) => ApplicationConfiguration = applicationConfiguration;

    protected override void Load(ContainerBuilder builder)
    {
        //dear inventory api service
        builder.Register(r =>
        {
            string baseUrl = ApplicationConfiguration["dearInventory:apiBaseUrl"];
            string accountId = ApplicationConfiguration["dearInventory:apiAccountId"];
            string applicationKey = ApplicationConfiguration["dearInventory:apiApplicationKey"]; ;
            var logger = r.Resolve<ILogger<DearInventoryApiService>>();

            return new DearInventoryApiService(logger, baseUrl, accountId, applicationKey);
        }).As<IDearInventoryService>();

        //register the application itself
        builder.RegisterType<CoreApplication>();
    }
}

1 Ответ

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

Option1

Ваше редактирование выглядит хорошо, но в соответствии с Принципом единой ответственности Я думаю, что лучше разделить между доступом ApplicationConfiguration и DefaultDependencyModule.

public class DefaultDependencyModule : Module
{
    public string BaseUrl { get; set; }
    public string AccountId { get; set; }
    public string ApplicationKey { get; set; }

    protected override void Load(ContainerBuilder builder)
    {
        //dear inventory api service
        builder.Register(r =>
        {
            var logger = r.Resolve<ILogger<DearInventoryApiService>>();

            return new DearInventoryApiService(logger, BaseUrl, AccountId, ApplicationKey);
        }).As<IDearInventoryService>();   
    }
}

И измените RegisterServices с помощью:

private static void RegisterServices()
{
    string baseUrl = ApplicationConfiguration["dearInventory:apiBaseUrl"];
    string accountId = ApplicationConfiguration["dearInventory:apiAccountId"];
    string applicationKey = ApplicationConfiguration["dearInventory:apiApplicationKey"];

    //register the default module
    containerBuilder.RegisterModule(new DefaultDependencyModule() {
        BaseUrl = baseUrl,
        AccountId = accountId,
        ApplicationKey = applicationKey
    });

    //code
});

Option2:

public class DefaultDependencyModule : Module
{
    protected override void Load(ContainerBuilder builder)
    {
        //dear inventory api service
        builder.Register((c, p) =>
        {
            string baseUrl = p.Named<string>("baseUrl");
            string accountId = p.Named<string>("accountId");
            string baseUrl = p.Named<string>("baseUrl");
            var logger = r.Resolve<ILogger<DearInventoryApiService>>();

            return new DearInventoryApiService(logger, baseUrl, accountId, applicationKey);
        })
        .As<IDearInventoryService>();   
    }
}

Время разрешения:

string baseUrl = ApplicationConfiguration["dearInventory:apiBaseUrl"];
string accountId = ApplicationConfiguration["dearInventory:apiAccountId"];
string applicationKey = ApplicationConfiguration["dearInventory:apiApplicationKey"];

DearInventoryService service = c.Resolve<DearInventoryService>(
    new NamedParameter("baseUrl", baseUrl), 
    new NamedParameter("accountId", accountId), 
    new NamedParameter("applicationKey", applicationKey)
);
...