I want to dynamically discover and register interface implementations. For the sake of argument I have two methods similar to these:
public void Register<TEvent>(IHandler<TEvent> handler) where TEvent : IEvent
public void Register<TEvent>(Action<TEvent> action) where TEvent : IEvent
{
Register<TEvent>(handler.Handle);
}
And the interfaces are like the following:
public interface IHandler<T> where T : IEvent
{
void Handle(T args);
}
public interface IEvent
{
}
Then I have the concrete implementations like:
public class ChangedEvent : IEvent
{...}
public class ChangedHandler : IHandler<ChangedEvent>
{
public void Handle(ChangedEvent args)
{
}
}
I can then discover all concrete implementations of IHandler<> in my assemblies, and I wanted to do something like this:
IList<Type> types = TypeFinder.GetImplementors(typeof(IHandler<>));
foreach (Type type in types)
{
object instance = Activator.CreateInstance(type);
Listeners.Register((IHandler<IEvent>)instance);
}
The code will compile, it's not invalid, but in run time the cast fails because it's invalid. However, if I cast to a concrete IEvent like:
IList<Type> types = TypeFinder.GetImplementors(typeof(IHandler<>));
foreach (Type type in types)
{
object instance = Activator.CreateInstance(type);
Listeners.Register((IHandler<ChangedEvent>)instance);
}
This cast is valid, and it will run. The problem is the dynamic of the scenario, I want to be able to discover the types and register them. I didn't want to create a non-generic interface for the handler, but I believe this is an impossible scenario because the framework doesn't have enough information to infer the required types. Is there any way to achieve this, or do you have any sugestions to achieve the desired result?
Many thanks.