Я хочу динамически обнаруживать и регистрировать реализации интерфейса. Ради аргумента у меня есть два метода, подобных этим:
public void Register<TEvent>(IHandler<TEvent> handler) where TEvent : IEvent
public void Register<TEvent>(Action<TEvent> action) where TEvent : IEvent
{
Register<TEvent>(handler.Handle);
}
И интерфейсы похожи на следующие:
public interface IHandler<T> where T : IEvent
{
void Handle(T args);
}
public interface IEvent
{
}
Тогда у меня есть конкретные реализации, такие как:
public class ChangedEvent : IEvent
{...}
public class ChangedHandler : IHandler<ChangedEvent>
{
public void Handle(ChangedEvent args)
{
}
}
Затем я могу обнаружить все конкретные реализации IHandler <> в моих сборках, и я хотел сделать что-то вроде этого:
IList<Type> types = TypeFinder.GetImplementors(typeof(IHandler<>));
foreach (Type type in types)
{
object instance = Activator.CreateInstance(type);
Listeners.Register((IHandler<IEvent>)instance);
}
Код скомпилируется, он не является недействительным, но во время выполнения приведение не выполняется, потому что оно недопустимо.
Однако, если я приведу к конкретному IEvent, как:
IList<Type> types = TypeFinder.GetImplementors(typeof(IHandler<>));
foreach (Type type in types)
{
object instance = Activator.CreateInstance(type);
Listeners.Register((IHandler<ChangedEvent>)instance);
}
Это приведение действительно, и оно будет запущено. Проблема заключается в динамике сценария, я хочу иметь возможность обнаруживать типы и регистрировать их.
Я не хотел создавать не универсальный интерфейс для обработчика, но я полагаю, что это невозможный сценарий, потому что среда не имеет достаточно информации для вывода требуемых типов.
Есть ли способ достичь этого, или у вас есть какие-либо предложения для достижения желаемого результата?
Большое спасибо.