Please suppose I have the following classes and interfaces:
public class ConcreteRepository : IRepository<T>, IEntityOwner
{ }
public interface IRepository<T>
{ }
public interface IEntityOwner
{ }
public class SomeModel
{ }
and suppose I have registered the following service in my Asp.Net Core 2.0 startup class:
services.AddScoped<IRepository<SomeModel>, ConcreteRepository>();
I can get the instance of ConcreteRepository like this:
var concreteRepositoryInstance =
httpContext.RequestServices.GetService(typeof(IRepository<SomeModel>))
as IRepository<SomeModel>;
How can I get the instance of ConcreteRepository by the type of ConcreteRepository?
I imagine something like this:
var concreteRepositoryInstance =
httpContext.RequestServices.GetService(typeof(ConcreteRepository))
as IEntityOwner;
Please note that I cannot use any generics to answer my question, because my use case refers to a custom attribute that takes the type of concreteRepository as an input parameter (and attributes cannot be generics by design).
What I tried so far:
(a) I checked and tried all httpContext.RequestServices.GetService... methods but they all require the type of interface with which the concrete type is registered with.
(b) I was thinking about getting all services from the dependency container, but IServiceProvider does not offer getting all services. I can only get them by the type of interface.
Had a discussion that i felt i needed some external input on. Normally always use interfaces instead of concrete types (on lists, injectable services and so forth). For example in lists i just pass around IEnumerable instead on List and so forth. The same applies for custom types (ICustomClass instead on CustomClass).
AsImplementedInterfaces () // register the service with all its public interfaces . SingleInstance (); // register the services as singletons In this example, Autofac will find all concrete classes in the assembly who's name ends with "Repository", and register them in the container against any public interfaces they implement.
In this example, Autofac will find all concrete classes in the assembly who's name ends with "Repository", and register them in the container against any public interfaces they implement. So for example, given the following classes and interfaces: services. AddSingleton < IStubRepository, StubRepository > (); services.
In general, you want to accept as abstract a type as possible, and return as concrete a type as possible, but the situation you came across isn't really a question of abstract vs. concrete types. If you want the caller to be responsible for making sure an argument is serializable, that needs to be specified in the interface.
Try registering type directly like so
public void ConfigureServices(IServiceCollection services)
{
// container will create the instance of this type
services.AddScoped<ConcreteRepository>();
}
Then you will be able to resolve type directly with
var concreteRepositoryInstance =
httpContext.RequestServices.GetService(typeof(ConcreteRepository))
as IEntityOwner;
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