2010-06-04 78 views
1

在谷歌搜索中,我似乎無法找到代理類型攔截事件的例子,它似乎並沒有爲我工作。有沒有一種方法可以做到這一點(即,當事件被調用時使用IInterceptor)?城堡DynamicProxy攔截事件

回答

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 
    } 
} 
+0

我遇到同樣的問題。你在哪裏把這個事件處理程序? – 2010-08-03 14:41:15

+0

6年後...事件連接到由IKernelEvents公開的Containers內核。 https://github.com/castleproject/Windsor/blob/master/docs/container-events.md – Konstantin 2016-12-06 21:19:31

2

我對此表示懷疑。 Castle Dynamic Proxy通過攔截代理上的呼叫來工作。事件不是在代理上進行的。它們是.NET框架處理的回調。

+2

這是正確的。使用DP,您可以攔截方法,包括事件訂閱和取消訂閱,但就是這樣。 – 2010-06-04 22:04:54

+0

謝謝,我的解決方案完成了我所尋找的東西,所以這不是必需的。 – Jeff 2010-06-05 20:26:41