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
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
}
}
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.
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. –
Merci, ma solution ci-dessous accomplit ce que je cherchais donc ce n'est pas nécessaire. – Jeff
J'ai le même problème. Où id vous mettez ce gestionnaire d'événements? –
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