Reputation: 1410
I am trying to learn how Action<T>
and Func<T>
are working, for this I've created a base class which requires an Action<AppConfiguration>
in it's constructor among other dependencies:
public abstract class GenericOracleTDRRepository<T> : IGenericTDRRepository<T>
{
protected GenericOracleTDRRepository(ILogger<GenericOracleTDRRepository<T>> logger,
Action<AppConfiguration> configuration,
IUpdateSqlStringGenerator<T> generator)
{
if (configuration is null)
{
throw new ArgumentNullException(nameof(configuration));
}
Logger = logger ?? throw new ArgumentNullException(nameof(logger));
configuration(AppSettings);
_generator = generator ?? throw new ArgumentNullException(nameof(generator));
}
public AppConfiguration AppSettings { get; private set; } = new AppConfiguration();
}
public class RmesgOracleReposityory : GenericOracleTDRRepository<RMesg>, IGenericTDRRepository<RMesg>
{
public RmesgOracleReposityory(ILogger<RmesgOracleReposityory> logger,
Action<AppConfiguration> appSettings,
IUpdateSqlStringGenerator<RMesg> generator) : base(logger, appSettings, generator)
{
Logger = logger;
}
public new ILogger<RmesgOracleReposityory> Logger { get; }
}
I am configuring it in my DI container:
services.AddScoped<IGenericTDRRepository<RMesg>, RmesgOracleReposityory>();
services.AddTransient<IUpdateSqlStringGenerator<RMesg>, UpdateSqlStringGenerator<RMesg>>();
I am not sure where and how should I pass a valid Action<AppConfiguration>
for this object?
Upvotes: 2
Views: 1450
Reputation: 169330
You need to define the Action<AppConfiguration>
to use somewhere.
If you for example define it in the Startup
class, you could use the overload of AddScoped
that accepts an IServiceProvider
to resolve the other dependencies and inject it like this:
void TheAction(AppConfiguration appConfiguration) { }
services.AddScoped<IGenericTDRRepository<RMesg>, RmesgOracleReposityory>(serviceProvider =>
{
var logger = serviceProvider.GetRequiredService<ILogger<RmesgOracleReposityory>>();
var generator = serviceProvider.GetRequiredService<IUpdateSqlStringGenerator<RMesg>>();
return new RmesgOracleReposityory(logger, TheAction, generator);
});
You might also define it in the RmesgOracleReposityory
class and pass it to the base class' constructor:
public class RmesgOracleReposityory : GenericOracleTDRRepository<RMesg>, IGenericTDRRepository<RMesg>
{
public RmesgOracleReposityory(ILogger<RmesgOracleReposityory> logger,
IUpdateSqlStringGenerator<RMesg> generator)
: base(logger, TheAction, generator)
{
Logger = logger;
}
private void TheAction(AppConfiguration appConfiguration) { }
public new ILogger<RmesgOracleReposityory> Logger { get; }
}
An Action<T>
just encapsulates a void
method that takes a single parameter of type T
.
Upvotes: 2