Перехват событий с помощью Castle DynamicProxy - PullRequest
1 голос
/ 04 июня 2010

При поиске в Google я не могу найти пример перехвата события для прокси-типа, и, похоже, он не работает для меня. Есть ли способ, которым я могу сделать это (т.е. использовать IInterceptor, когда вызывается событие)?

Ответы [ 2 ]

2 голосов
/ 05 июня 2010

Я закончил тем, что использовал событие 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
    }
}
2 голосов
/ 04 июня 2010

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

...