I have an asp.net core web app with multiple parameters in appSettings.json file.
I didnt' want to have services having IOptions<MyObject> in the constructor.
I wanted MyObject in the constructor. So I found the following article: https://weblog.west-wind.com/posts/2017/dec/12/easy-configuration-binding-in-aspnet-core-revisited which is very interesting.
But I want to go further. I would like to create an extension method to generate the injection.
Here is what I would like to do:
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
namespace Common.WebTools.Extensions
{
public static class IServiceCollectionExtensions
{
public static IServiceCollection AddSingletonConfigurationObject<T>(this IServiceCollection services,
IConfiguration configuration,
string appSettingsKey) where T:new()
{
var obj2 = new T();
configuration.Bind(appSettingsKey, obj);
services.AddSingleton(obj2); //compilation failed
return services;
}
}
}
And then in my ConfigureServices method I can call
services.AddSingletonConfigurationObject<Common.Tools.Configuration.GoogleAnalyticsConfiguration>(Configuration, "GoogleAnalytics");
But I Have a compliation error on this line:
services.AddSingleton(obj2);
Does somebody know how could I correct the error?
You can use services.AddScoped to use only 1 instance in the scope request. So in general improvement compare to AddTransient
services.AddScoped(typeof(IGenericRepository<>), typeof(GenericRepository<>));
So my interface and class will look like this
public interface IGenericRepository<T> where T : class
public class GenericRepository<T> : IGenericRepository<T> where T : class
I was able to use this style to encapsulate (as an extension method)
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
namespace MyProject.DependencyInjection
{
public static class MyEncapsulatedIocRegistration
{
public static IServiceCollection AddTypeT<T>(this IServiceCollection services) where T : class
{
services.AddSingleton<IMyThingInterface<T>, MyThingConcrete<T>>();
return services;
}
}
}
As stated in the comments you should set the generic constraint to where T: class in order to satisfy the constraint of the AddSingleton call.
Reference AddSingleton(IServiceCollection, TService)
Additionally you can bind the object graph using ConfigurationBinder.Get<T>
Reference Configuration in ASP.NET Core : Bind to an object graph
ConfigurationBinder.Get<T>binds and returns the specified type.Get<T>is more convenient than usingBind.
like in the following example
public static class IServiceCollectionExtensions {
public static IServiceCollection AddSingletonConfigurationObject<TService>(
this IServiceCollection services,
IConfiguration configuration,
string appSettingsKey) where TService: class
{
var setting = configuration.GetSection(appSettingsKey).Get<TService>();
services.AddSingleton(setting);
return services;
}
}
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