I have an application where I have multiple connection strings for my DbContext
implementations. To support this in the consuming classes, I've created an IDbContextProvider
interface with a Get
method that can provide me with the DbContext
instances I need.
I've also got an ICommandHandler
thing going, and I'm trying to create a decorator that will call DbContext.SaveChangesAsync()
on successful command execution. I'm registering my decorator like this:
container.RegisterDecorator(typeof(ICommandHandler<>),
typeof(SaveChangesCommandHandlerDecorator<>));
Now, because I don't want to add a type parameter for the DbContext
implementaiton, and I know all classes derived from DbContext
have a SaveChangesAsync()
method, I figured I could use covariance. So my interface looks like this:
public public interface IDbContextProvider<out TDbContext> where TDbContext : DbContext
{
TDbContext Get(DbPrivileges privileges);
}
And the relevant part of my decorator:
public class SaveChangesCommandHandlerDecorator<TCommand> : ICommandHandler<TCommand>
where TCommand : ICommand
{
private readonly ICommandHandler<TCommand> _handler;
private readonly IDbContextProvider<DbContext> _dbContextProvider;
public SaveChangesCommandHandlerDecorator(
ICommandHandler<TCommand> handler, IDbContextProvider<DbContext> dbContextProvider)
{
_handler = handler;
_dbContextProvider = dbContextProvider;
}
...
However, when I call Verify()
on my container, it complains that the IDbContextProvider
is invalid, as it's looking for the "base" IDbContextProvider<DbContext>
instead of one of the ones registered in my app.
The constructor of type SaveChangesCommandHandlerDecorator<CreateUserCommand> contains the parameter with name 'dbContextProvider' and type IDbContextProvider<DbContext> that is not registered.Please ensure IDbContextProvider<DbContext> is registered, or change the constructor of SaveChangesCommandHandlerDecorator<CreateUserCommand>. Note that there exists a registration for a different type (Redacted).IDbContextProvider<TDbContext> while the requested type is (Redacted).IDbContextProvider<Microsoft.EntityFrameworkCore.DbContext>.
This actually makes sense, since Simple Injector has no way of knowing what concrete type to inject into the dbContextProvider
parameter.
Is there any way of customizing the way my decorator is created, so that it can peek at the dependencies of the underlying ICommandHandler
implementation's dependencies, and pick the IDbContextProvider
signature from there on creation? So if my command handler has a IDbContextProvider<AwesomeDbContext>
, I want that to be resolved for my decorator as well.