Reputation: 301
I'm trying to configure an API which a controller use depency injection to inject an object to this controller
public class BaseAPIController
{
private readonly Repository _repository;
public BaseAPIController(Repository repository)
{
_repository = repository;
}
// some common functions and properties are declared here
}
public class AccountController : BaseAPIController
{
public AccountController(Repository repository) : base(repository)
{ }
}
but it throws an exception that tells "Some services are not able to be constructed..."
I tried a solution that use ILogger<Repository>
instead of using Repository
instance then this runs properly
public class AccountController : BaseAPIController
{
public AccountController(ILogger<Repository> repository) : base(repository)
{ }
}
the registion service in startup.cs code
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddScoped<IRepository, Repository>();
services.AddSingleton<WeatherForecastController, WeatherForecastController>();
}
and the declaration of Repository class
public interface IRepository
{
void DoSomething1();
void DoSomething2();
void DoSomething3();
}
public class Repository : IRepository
{
public readonly string _connectionString;
public Repository(string connectionString)
{
_connectionString = connectionString;
}
public void DoSomething1() {}
public void DoSomething2() {}
public void DoSomething3() {}
}
How can I archive the configuration above without using ILogger instance Thanks
Upvotes: 0
Views: 53
Reputation: 172826
This is the registration you made:
services.AddScoped<IRepository, Repository>();
But this is AccountController
's constructor:
AccountController(Repository repository)
Notice how AccountController
is depending on the concrete type Repository
; not on the IRepository
interface. Because of this registration, Repository
can only be resolved through its IRepository
interface, but not directly (that's by MS.DI's design).
The solution, therefore, is to change AccountController
's constructor to the following:
AccountController(IRepository repository)
Upvotes: 1
Reputation: 422
The issue is that DI cannot create an instance of Repository
because there is no parameterless constructor. Take a look at the docs for injecting settings rather than requiring a string in the constructor. Add your connection string to your appsettings.json file:
{
"AppSettings": {
"ConnectionString": "<connection_string>"
}
}
In ConfigureServices
register your settings class:
public class AppSettings
{
public string ConnectionString;
}
public void ConfigureServices(IServiceCollection services)
{
services.Configure<AppSettings>(Configuration.GetSection(AppSettings));
...
}
Then your Repository class constructor would look like this:
public Repository(IOptions<PositionOptions> options)
{
_connectionString = options.Value.ConnectionString;
}
You also need to inject the interface IRepository
, not the concrete class into your controller.
public class BaseAPIController
{
private readonly IRepository _repository;
public BaseAPIController(IRepository repository)
{
_repository = repository;
}
// some common functions and properties are declared here
}
Upvotes: 1