【发布时间】:2011-04-08 09:09:19
【问题描述】:
我想动态发现和注册接口实现。为了论证,我有两种类似的方法:
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);
}
这个演员表是有效的,它将运行。问题是场景的动态,我希望能够发现类型并注册它们。 我不想为处理程序创建一个非通用接口,但我相信这是一个不可能的场景,因为框架没有足够的信息来推断所需的类型。 有什么方法可以实现这一点,或者您有什么建议可以达到预期的效果吗?
非常感谢。
【问题讨论】:
-
ChangedEvent根本不继承自IHandler<IEvent>,而仅继承自IEvent,即使可以从非泛型向下转换为泛型,您的演员阵容也不会起作用,或者我缺少什么? -
你是绝对正确的。非常抱歉,我没有包含处理程序实现的代码。我已经更新了问题。
标签: c# generics reflection casting