I am working on handling domain events on save by adding them to a List on our Entities.
public abstract class Entity
{
public List<IDomainEvent> DomainEvents;
// code truncated
}
my interface for IDomainEvent and Handlers are as follows:
public interface IDomainEvent
{
}
public interface Handles<T> where T : IDomainEvent
{
void Handle(T args);
}
This should enable me to get the list of handler that can handle that event such as
AssignActionPlanToCustomer
public class AssignActionPlanToCustomer: Handles<ActionPlanCreatedForCustomer>
{
// code truncated
}
public IEnumerable<Handles<T>> Handlers<T>(T domainEvent) where T : IDomainEvent
{
var actualType = typeof(Handles<>).MakeGenericType(domainEvent.GetType());
foreach (var i in _serviceProvider.GetServices(actualType))
{
yield return (Handles<T>)i;
}
}
The problem is that
- If I don't convert the generic type to the specific type, I get nothing from my
_serviceProvider
i.e. Service Provider cannot findHandles<IDomainEvent>
- If I do get the specific type, the return type of
GetServices(type)
is a genericIEnumerable<object?>
that cannot be cast to the genericIEnumerable<Handles<IDomainEvent>>
- If I try to return it as a
dynamic
type, the runtime cannot find the correct constructor.
There has to be an easier way to handle either the service provider, or the casting of the specific event to the more general event. What am I missing here?
currently I am able to work around it by doing the following:
public interface Handles<out T> where T : IDomainEvent
{
void Handle(IDomainEvent args);
}
This works, except I have to manually cast the IDomainEvent to the derived class inside of each handler. It's a bit annoying, but it does work.