I have defined the following interface:
public interface ICustomService<T> where T : CustomObject
{
IEnumerable<T> GetById(int Id);
...
}
And 2 implementations of it where MyObject1
& MyObject2
both inherit from CustomObject
public class CustomService1 : ICustomService<MyObject1>
{
public IEnumerable<MyObject1> GetById(int Id)
{
...
}
}
public class CustomService2 : ICustomService<MyObject2>
{
public IEnumerable<MyObject2> GetById(int Id)
{
...
}
}
I try registering both of these as ICustomService<CustomObject>
but get the error:
There is no implicit reference conversion from 'CustomerService1' to 'ICustomService<CustomObject>'
Instead registering like this:
services.AddTransient<ICustomService<MyObject1>, CustomService1>();
services.AddTransient<ICustomService<MyObject2>, CustomService2>();
When registering like above, my IEnumerable services
is empty:
public ThirdService(IEnumerable<ICustomService<CustomObject>> services)
{
}
How can I inject all implementation of ICustomService
into ThirdService
?
I'm trying to do this so that ThirdService
can be given an ID and then fetch all CustomObject
with that Id using GetById
on all the services.
CodePudding user response:
Assuming there are no additional interface methods that have parameters of type T
, mutable properties of type T
, or methods that return a generic type that uses T
in a non-covariant way, you can make that T
covariant using out
:
public interface ICustomService<out T> where T : CustomObject
This would make your registration attempt valid:
services.AddTransient<ICustomService<MyObject>, CustomService1>();
services.AddTransient<ICustomService<MyObject>, CustomService2>();
Covariance ensures that CustomService1
and CustomService2
can safely be used in place of a ICustomService<MyObject>
, despite them both declaring a subclass of MyObject
as the generic argument.