简体   繁体   中英

How to register a service in ASP.NET Core that is created by a factory?

I am getting the following error:

Unable to resolve service for type 'IMyRepository' while attempting to activate 'MyController'.

I understand that my application is failing on the dependency injection.

However I'm not sure how to correct this error.

My IMyRepository looks lie this:

public interface IMyRepository
{
  public Delete(Guid Id);
  public Get(Guid Id);
  //etc..
}

We set the following interface up when we created the unit tests.

public IMyRepositoryFactory
{
  IRepository CreateRepository();
}

The constructor in my Controller:

private readonly IRepository _repo;

public MyController(IRepository repo)
{
   _repo = repo;
}

I can pass the factory into the constructor, however that would require me to redo the unit testing modules since they are all passing IRepository to the controller.

Ex. (In Startup ConfigureServices)
services.AddTransient<IMyRepositoryFactory, ConcreteRepositoryFactory>();

I would prefer to leave the controller constructors and testing classes as is. So is there a way to setup DI in this scenario (Where I am passing the IRepository to the controller)?

EDIT:

public class ConcreteRepositoryFactory : IMyRepositoryFactory
{
    public ConcreteRepositoryFactory(string connString);
    public IMyRepository CreateRepository();
}

I'm not exactly clear on what you're trying to achieve here. Simplistically, you need to bind an implementation of IMyRepository if you want to inject IMyRepository :

services.AddScoped<IMyRepository, MyRepository>();

If you're saying you want to inject the implementation via a factory, you can simply provide a factory to the service registration:

services.AddScoped<IMyRepository>(p =>
    p.GetRequiredService<IMyRepositoryFactory>().CreateRepository());

You are adding a Transcient IMyRepositoryFactory linked to a ConcreteRepositoryFactory .

So you cannot inject a IRepository class in your controller, because asp.net Core doesn't know your IRepository class in the transcient injections.

You have to inject instead the ConcreteRepositoryFactory class to your controller like this :

public MyController(ConcreteRepositoryFactory repo)

And you can store in your readonly property as IMyRepositoryFactory _repo .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM