Zeus82
Zeus82

Reputation: 6375

Constructor with non-DI and DI parameters

I'm creating a service that requires some config parameters and a logger. Here is the constructor for my service:

public StorageProvider(string directory, ILogger<StorageProvider> logger)

I just added the logger. I used to initalize it like this in my startup.cs:

services.AddSingleton<IStorageProvider>(
    new StorageProvider(Configuration["TempStorage.Path"]));

The directory parameter comes from the config file, and the logger gets DI'ed. How do I setup my IStorageProvider?

Upvotes: 1

Views: 1201

Answers (2)

Steven
Steven

Reputation: 172606

You should do the following:

  • Wrap the configuration value TempStorage:Path into its own configuration class, e.g. StorageProviderSettings.
  • Let StorageProvider depend upon that new configuration class.
  • Register that configuration class as singleton into the ASP.NET configuration system.

Example:

public sealed class StorageProviderSettings
{
    public readonly string TempStoragePath;

    public StorageProviderSettings(string tempStoragePath)
    {
        if (string.IsNullOrWhiteSpace(tempStoragePath))
            throw new ArgumentException(nameof(tempStoragePath));
        this.TempStoragePath = tempStoragePath;
    }
}

public sealed class StorageProvider : IStorageProvider
{
    public StorageProvider(
        StorageProviderSettings settings, ILogger<StorageProvider> logger)
    {
        // ...
    }
}

// Registration
services.AddSingleton(new StorageProviderSettings(Configuration["TempStorage.Path"]));
services.AddSingleton<IStorageProvider, StorageProvider>();

Upvotes: 2

ssmith
ssmith

Reputation: 8922

Use the Options pattern as Tratcher suggests in a comment. Read more in the official docs on Configuration.

Basically you define a class to be hold the value you need:

public class StorageProviderOptions
{
    public string TempStoragePath { get; set; }
}

Then in ConfigureServices you register the type:

services.Configure<StorageProviderOptions>();

In your code, you request IOptions<StorageProviderOptions> and set this to an instance of StorageProviderOptions:

public class SomeController
{
    private readonly StorageProviderOptions _options;

    public SomeController(IOptions<StorageProviderOptions> options)
    {
        _options = options.Value;
    }
}

Finally, make sure you have an element in your configuration source that matches the TempStoragePath name. Alternately, you can register the option in ConfigureServices using code:

services.Configure<ServiceProviderOptions>(o => o.TempStoragePath = "temp");

Upvotes: 0

Related Questions