For example, I have a class CreateAutoDeletingRequestReachSuspensionDaysLimitAndInactiveLongTimeService with the following dependencies:
protected readonly IDeviceService _deviceService;
protected readonly IAzureFunctionLogService _azureFunctionLogService;
protected readonly IDeviceValidationService _deviceValidationService;
so, I can create ctor for the class:
public CreateAutoDeletingRequestReachSuspensionDaysLimitAndInactiveLongTimeService(
IDeviceService deviceService,
IDeviceValidationService deviceValidationService,
IAzureFunctionLogService azureFunctionLogService)
{
_deviceService = deviceService;
_deviceValidationService = deviceValidationService;
_azureFunctionLogService = azureFunctionLogService;
}
then inject all dependencies like:
services.AddTransient<CreateAutoDeletingRequestReachSuspensionDaysLimitAndInactiveLongTimeService>();
services.AddSingleton<Func<CreateAutoDeletingRequestReachSuspensionDaysLimitAndInactiveLongTimeService>>(sp =>
() => sp.GetRequiredService<CreateAutoDeletingRequestReachSuspensionDaysLimitAndInactiveLongTimeService>()
);
and then use it like this:
private readonly Func<CreateAutoDeletingRequestReachSuspensionDaysLimitAndInactiveLongTimeService> _service;
public FunctionDebugPendingStatusWorkflow(
Func<CreateAutoDeletingRequestReachSuspensionDaysLimitAndInactiveLongTimeService> service,
//....
ILoggerFactory loggerFactory)
{
_service = service;
//....
_logger = loggerFactory.CreateLogger<FunctionDebugPendingStatusWorkflow>();
}
so, it works fine.
But how can I add one more param to ctor, which set in caller? For example, I want to pass deviceId to ctor and can't describe it as dependency using dependency injector in Program.cs (in my case)
I have to create "Init" method like this:
public void Init(int deviceId)
{
_device = _deviceService.GetDeviceById(deviceId);
// ...
}
and add logic there.
Then I have to call _service.Init(...); before using _service methods. It works, but all disadvantages and potential problems are obviously (if forgot to call etc)
How to pass this parameter using DI ?
You can do something like this:
serviceCollection
.AddScoped<IYourService>(s => new YourService(
s.GetService<YourPreviouslyInjectedService1>(),
s.GetService<YourPreviouslyInjectedService2>(),
s.GetService<YourPreviouslyInjectedService3>(),
deviceId
)
);
But I would advise against it and use IOptions with a configuration object injected like:
.Configure<YourConfigurationWithDeviceIdProperty>(
c => builder.Configuration.GetSection("YourConfigSectionInAppSettings").Bind(c)
)
First, you are avoiding all this noise in the DI layer and second, you are making sure that you are injecting the correct setting as your constructor would accept a parameter of a specific type and not a primitive which can be anything ("123", "banana", etc).
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