2010-06-04 5 views
1

Dans Google, je n'arrive pas à trouver un exemple d'événement d'interception sur un type proxy et cela ne semble pas fonctionner pour moi. Existe-t-il un moyen de le faire (par exemple, utiliser un IInterceptor lorsqu'un événement est appelé)?Interception d'événement avec Castle DynamicProxy

Répondre

2

Je fini par utiliser l'événement ComponentCreated, puis en ajoutant un gestionnaire d'événements dynamique avec un DynamicMethod pour accomplir ce que je voulais:

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

J'ai le même problème. Où id vous mettez ce gestionnaire d'événements? –

+0

6 ans plus tard ... les événements sont câblés sur le noyau des conteneurs exposé par IKernelEvents. https://github.com/castleproject/Windsor/blob/master/docs/container-events.md – Konstantin

2

J'en doute. Castle Dynamic Proxy fonctionne en interceptant les appels effectués sur le proxy. Les événements ne sont pas effectués sur le proxy. Ce sont des rappels gérés par le framework .NET.

+2

C'est exact. Avec DP, vous pouvez intercepter des méthodes, y compris l'inscription à un événement et la désinscription, mais c'est tout. –

+0

Merci, ma solution ci-dessous accomplit ce que je cherchais donc ce n'est pas nécessaire. – Jeff

Questions connexes