Closed stevenrobertscrew closed 8 months ago
Change your decorator to the following:
public class ReservationAuditStoreDecorator<TCommand>
: IHandleCommandAsync<TCommand, Id>
{
private readonly IReservationAuditStore _reservationAuditStore;
private readonly IHandleCommandAsync<TCommand, Id> _decorated;
public ReservationAuditStoreDecorator(
IHandleCommandAsync<TCommand, Id> decorated,
IReservationAuditStore reservationAuditStore)
{
_reservationAuditStore = reservationAuditStore;
_decorated = decorated;
}
public async Task<IOpResult<Id>> HandleAsync(TCommand command)
{
var result = await _decorated.HandleAsync(command);
if (result.IsFailure)
{
return result;
}
var auditStoreResult = await _reservationAuditStore.AppendAsync(
result.Value.ReservationId, command);
return auditStoreResult.IsFailure
? OpResult.Fail<Id>(auditStoreResult.Exception)
: result;
}
}
And register it as follows:
container.RegisterDecorator(
typeof(IHandleCommandAsync<,>),
typeof(ReservationAuditStoreDecorator<>),
Lifestyle.Scoped);
In other words, you make the decorator generic, giving it a TCommand
generic type argument that maps to the TCommand
argument of the ICommandHandlerAsync<TCommand, TResult>
interface, where the TResult
is filled in with Id
. Of course every part of the code that refers to CreateReservationByUser
needs to be replaced by TCommand
. This decorator can be registered as shown above and Simple Injector will do the rest.
ugh. I guess I missed a spot. I separately have a decorator for the 'normal' commands (e.g. ones without a return type). Just using different names would solve for that... DUH! Thanks @dotnetjunkie
hello,
I need to decorate a command handler but only for commands that have a specific return type. In this case my command has a return type, mainly just the id that was created/updated or whatever.
I have a decorator that I only wish to apply when
TResult
is a specific type; I need to do something with that specific type like log it. Here's an example of that decoratorThis works when I register like this
When this is the only use case I don't mind, but now along comes a secondary command that needs the same log. Both return types have an Id property that I need to log. I tried creating an interface to make this clearer like this
and registering the decorator like this
For reasons that will no doubt be obvious to you, this compiles and runs but
ReservationAuditStoreDecorator
is never decorating the handler. I'm sure I'm missing something just silly.I have considered using the predicate way of registering the decorator and then inside the decorator casting the result to
Id
but that means I'm depending on the registration predicate when I'd rather depend on type safety. Please can you help?