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.
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?
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.
You need to create a class with MyOptions[] as a property and the inject that class and add the whole configuration without section.
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.
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
}
}
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"));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With