Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 333
mmix Avatar asked Aug 17 '18 11:08

mmix


People also ask

What is Ioptions?

IOptionsMonitor is a Singleton service that retrieves current option values at any time, which is especially useful in singleton dependencies. IOptionsSnapshot is a Scoped service and provides a snapshot of the options at the time the IOptionsSnapshot<T> object is constructed.

How do you inject IOptionsMonitor?

You need to create a class with MyOptions[] as a property and the inject that class and add the whole configuration without section.

What is services AddOptions?

AddOptions(IServiceCollection) Adds services required for using options. AddOptions<TOptions>(IServiceCollection) Gets an options builder that forwards Configure calls for the same named TOptions to the underlying service collection.


2 Answers

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
    }
}
like image 107
Slawomir Brys Avatar answered Oct 02 '22 16:10

Slawomir Brys


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"));
like image 22
pim Avatar answered Oct 02 '22 17:10

pim