How to register dependency injection with generic types? (.net core)
Solution 1
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
Solution 2
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;
}
}
Solution 3
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;
}
}
}
Rémy
Updated on July 09, 2022Comments
-
Rémy 11 months
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?
-
AMG over 3 yearsSo how would the target for the injected instance actually look?
-
AMG over 3 yearsIs it even possible with constructor injecton since it requires a type argument? private readonly IGenericRepository<???> _repository;
-
mRizvandi over 2 yearsprivate readonly IGenericRepository<T> GenericRepository; ....... in the constructor parameters use ....IGenericRepository<T> genericRepository; and in body of constructor set the property .... GenericRepository = genericRepository. you have to use it in generic class, with same T inheritance.
-
Patrick Szalapski over 1 yearAny idea why this idea can't work with
AddTransient
?