В поиске в Google я не могу найти пример перехвата события на проксируемом типе, и, похоже, он не работает для меня. Есть ли способ сделать это (т. Е. Использовать IInterceptor при вызове события)?
Перехват событий с помощью Castle DynamicProxy
Ответы (2)
Я сомневаюсь. Castle Dynamic Proxy работает, перехватывая звонки, сделанные через прокси. События на прокси не производятся. Это обратные вызовы, обрабатываемые платформой .NET.
person
PatrickSteele
schedule
04.06.2010
Это правильно. С DP вы можете перехватывать методы, включая подписку на события и отмену подписки, но это все.
- person Krzysztof Kozmic; 05.06.2010
Спасибо, мое решение ниже выполняет то, что я искал, поэтому в этом нет необходимости.
- person Jeff; 06.06.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
}
}
person
Jeff
schedule
04.06.2010
У меня такая же проблема. Куда вы положили этот обработчик событий?
- person Mike Therien; 03.08.2010
6 лет спустя ... событие связано с ядром контейнеров, предоставленным IKernelEvents. github.com/castleproject/Windsor/blob/master/docs/
- person Konstantin; 07.12.2016