在谷歌搜索中,我似乎找不到在代理类型上拦截事件的示例,而且它似乎对我不起作用。有没有办法可以做到这一点(即在调用事件时使用 IInterceptor)?
问问题
1276 次
2 回答
2
我对此表示怀疑。Castle Dynamic Proxy 通过拦截代理上的调用来工作。事件不在代理上进行。它们是由 .NET 框架处理的回调。
于 2010-06-04T17:54:09.590 回答
2
我最终使用了 ComponentCreated 事件,然后添加了一个带有 DynamicMethod 的动态事件处理程序来完成我想要的:
private static readonly MethodInfo internalPublishEventMethod =
typeof(EventPublisher).GetMethod("PublishEvent", BindingFlags.Static | BindingFlags.NonPublic);
private void Container_ComponentCreated(global::Castle.Core.ComponentModel model, object instance)
{
if (instance != null)
{
Type type = instance.GetType();
var eventPublisherAttribute = type.GetAttribute<EventPublisherAttribute>();
if (eventPublisherAttribute != null)
{
foreach (EventInfo ei in type.GetEvents())
{
if (eventPublisherAttribute.PublishAllEvents || ei.GetCustomAttributes(typeof(PublishedEventAttribute), false).Length > 0)
{
// emit an event handler
MethodInfo invoke = ei.EventHandlerType.GetMethod("Invoke");
Type[] parameters = invoke.GetParameters().Select(p => p.ParameterType).ToArray();
var method = new DynamicMethod(string.Empty, null, parameters, instance.GetType(),
true);
ILGenerator generator = method.GetILGenerator();
// sender
generator.Emit(OpCodes.Ldarg_0);
// args
generator.Emit(OpCodes.Ldarg_1);
// topic
generator.Emit(OpCodes.Ldstr, ei.Name);
generator.Emit(OpCodes.Call, internalPublishEventMethod);
generator.Emit(OpCodes.Ret);
Delegate d = method.CreateDelegate(ei.EventHandlerType);
ei.AddEventHandler(instance, d);
}
}
}
}
}
private static void PublishEvent(object sender, EventArgs e, string topic)
{
if (e != null)
{
// do stuff
}
}
于 2010-06-04T20:06:11.967 回答