I'm confused on how to pass on dependencies that come from the DI Container onto a constructor of a class.
I've got the following registrations:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddDbContext<StockManagerContext>(o =>
o.UseSqlServer(Configuration.GetConnectionString("connectionString")));
services.AddTransient<ITxnNoGenerationRepository, TxnNoGenerationService>();
services.AddScoped<IResultRepository, ResultService>();
services.AddTransient<ICustomerRepository>(c => #<-- Compile error here
new CustomerService(
c.GetRequiredService<StockManagerContext>(),
new TxnNoGenerationService(
c.GetRequiredService<StockManagerContext>())),
new ResultService());
}
But I'm getting a compile on the marked line above. The C# compiler complains:
There is no argument given that corresponds to the required parameter 'resultrepository' of CustomerService.CustomerService(StockManagerContex,ITxnNoGenerationRepository,IResultRepository)"
This are my interface definitions:
public interface ICustomerRepository
{
Task<Result> Get();
Task<Result> Post(CustomerDetail customerDetail);
}
public interface IResultRepository
{
Result ReturnSuccessResult();
Result ReturnErrorResult();
}
public interface ITxnNoGenerationRepository
{
Task<NextNo> TxnNoGeneration(string code);
}
And this is my service class that seems to cause the compile error:
public class CustomerService : ICustomerRepository
{
private readonly StockManagerContext _context;
private readonly ITxnNoGenerationRepository _txnNoGenerationRepositiory;
private readonly IResultRepository _resultRepository;
public CustomerService(
StockManagerContext context,
ITxnNoGenerationRepository txnNoGenerationRepository,
IResultRepository resultRepository)
{
_context = context;
_resultRepository = _resultRepository;
_txnNoGenerationRepositiory = txnNoGenerationRepository;
}
public async Task<Result> Get() ...
public async Task<Result> Post(CustomerDetail customerDetail) ...
}
How can I pass these dependancies in Startup.cs class?
The compile error is caused by misplacement of a bracket. This is the code you have (indenting mine):
services.AddTransient<ICustomerRepository>(c =>
new CustomerService(
c.GetRequiredService<StockManagerContext>(),
new TxnNoGenerationService(
c.GetRequiredService<StockManagerContext>())),
new ResultService());
With this indenting you can more easily see the issue. One bracket should be moved to let the code become this:
services.AddTransient<ICustomerRepository>(c =>
new CustomerService(
c.GetRequiredService<StockManagerContext>(),
new TxnNoGenerationService(
c.GetRequiredService<StockManagerContext>()),
new ResultService()));
You are, however, using the lambda/factory syntax to register CustomerService
. You should prefer the simpler Auto-Wiring syntax:
services.AddTransient<ICustomerRepository, CustomerService>();
With this registration, the DI Container will find the dependencies on your behalf and will inject them automatically into CustomerService
's constructor. This leads to more maintainable code.