Reputation: 630
I have the following use case:
I have created generic-endpoint strucure in my ASP.NET Core WebAPi project.
And now I want to write an extention method to ServiceCollection
to register my Endpoint
s to DI easily.
Now I will try to demonstrate what I want. Let's say we have:
interface IEndPoint<TInput, TOutput>
{
TOutput Execute(TInput input);
}
class StrToIntEndPoint : IEndPoint<string, int>
{
public int Execute(string input)
{
return int.Parse(input);
}
}
class ServiceCollection { }
static class ServiceCollectionServiceExtensions
{
public static void AddScoped<TService, TImplementation>(this ServiceCollection services) where TImplementation : TService
{
}
}
static class MyCustomExt
{
// Here, I have to add TInput, TOutput type parameters to AddEndpoint method too.
public static void AddEndpoint<T, TInput, TOutput>(this ServiceCollection services) where T: IEndPoint<TInput, TOutput>
{
services.AddScoped<IEndPoint<TInput, TOutput>, T>();
}
}
class Program
{
static void Main()
{
var services = new ServiceCollection();
// Compile Error: Incorrect number of type parameters
services.AddEndpoint<StrToIntEndPoint>();
// fine
services.AddEndpoint<StrToIntEndPoint, string, int>();
}
}
My question is why compiler doesn't resolve string
and int
as type parameters for AddEndpoint
via refering to StrToIntEndPoint
?
Upvotes: 0
Views: 167
Reputation: 630
I ended up with the following solution for my case:
static class MyCustomExt
{
public static IServiceCollection AddScopedWitInterfaces<T>(this IServiceCollection services)
{
Type type = typeof(T);
Type[] interfaces = type.GetInterfaces();
foreach (Type interfaceType in interfaces)
{
services.AddScoped(interfaceType, type);
}
return services;
}
}
And register my service in ConfigureServices
:
services.AddScopedWitInterfaces<StrToIntEndpoint>();
Upvotes: 1
Reputation: 36563
Sadly it’s just not the way generic constraints/arguments work. You either specify NO generic type arguments and the compiler infers all arguments, or you specify all of them.
Upvotes: 1