mmix
mmix

Reputation: 6278

Simplified approach to IOptions<T>

I am trying to get a .NET Framework class library in line with an ASP.NET Core 2.1 application while using builtin DI mechanism. Now, I created a config class and added appropriate section to appsettings.json:

services.Configure<MyConfig>(Configuration.GetSection("MyConfiguration"));
services.AddScoped<MyService>();

In class lib:

public class MyService 
{
    private readonly MyConfig _config;

    public MyService(IOptions<MyConfig> config)
    {
        _config = config.Value;
    }
}

However, in order to build this classlib I have to add Microsoft.Extensions.Options NuGet package. The problem is that package carries a hell of a lot of dependencies which seem rather excessive to add just for the sake of one interface.

enter image description here

So, the question ultimately is, "is there another approach I can take to configure a DI service located in .NET Framework class library which is not dependency heavy?

Upvotes: 10

Views: 6077

Answers (3)

pim
pim

Reputation: 12577

I bumped into this problem a little while ago, if you can even call it a problem really. I think we all tend to get a little shell-shocked when we see a dependency list like that. But as @Tseng mentioned, it's really not a big deal to include a bunch of extra tiny assemblies (they'll be included in the bin already anyways by virtue of a reference in another project). But I will admit it's annoying to have to include them just for the options interface.

How I solved it was by resolving the service dependency in startup.cs and adjust the service's constructor accordingly:

services.AddTransient<MyService>(Configuration.GetConfiguration("MyConfiguration"));

Upvotes: 1

Slawomir Brys
Slawomir Brys

Reputation: 361

Check this article written by Filip Wojcieszyn.

https://www.strathweb.com/2016/09/strongly-typed-configuration-in-asp-net-core-without-ioptionst/

You add extension method:

public static class ServiceCollectionExtensions
{
    public static TConfig ConfigurePOCO<TConfig>(this IServiceCollection services, IConfiguration configuration) where TConfig : class, new()
    {
        if (services == null) throw new ArgumentNullException(nameof(services));
        if (configuration == null) throw new ArgumentNullException(nameof(configuration));

        var config = new TConfig();
        configuration.Bind(config);
        services.AddSingleton(config);
        return config;
    }
}

Apply it in configuration:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();
    services.ConfigurePOCO<MySettings>(Configuration.GetSection("MySettings"));
}

And then use it:

public class DummyService
{
    public DummyService(MySettings settings)
    {
        //do stuff
    }
}

Upvotes: 7

TheBlueSky
TheBlueSky

Reputation: 5948

If you don't care about whatever IOptions provides you, why not just inject IConfiguration into your service?

public class MyService
{
    private readonly IConfiguration _config;

    public MyService(IConfiguration config)
    {
        _config = config;
    }

    public void DoSomething()
    {
        var value = _config["SomeKey"];

        // doing something
    }
}

Upvotes: 0

Related Questions