2010-06-04 6 views
1

В googling Я не могу найти пример перехвата события на прокси-типа, и он, похоже, не работает для меня. Есть ли способ, которым я могу это сделать (например, использовать 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

У меня такая же проблема. Где id вы помещаете этот обработчик событий? –

+0

6 лет спустя ... события подключены к ядру контейнеров, выставленному IKernelEvents. https://github.com/castleproject/Windsor/blob/master/docs/container-events.md – Konstantin

2

Я сомневаюсь. Замок Dynamic Proxy работает, перехватывая вызовы, сделанные на прокси. События не выполняются на прокси-сервере. Это обратные вызовы, выполняемые платформой .NET.

+2

Это правильно. С помощью DP вы можете перехватывать методы, включая подписку на события и отмену подписки, но это все. –

+0

Спасибо, мое решение ниже выполняет то, что я искал, поэтому это необязательно. – Jeff

Смежные вопросы