故事以这种方式开始,我使用Castle EventWiring工具来定义我的类中事件的监听器,并且它工作正常,我曾经提出这样的事件:
if (null != BlaBlaEvent)
{
BlaBlaEvent(someData);
}
最近我面临业务需求,并认为最好的解决方案是使用代理模式,所以我使用DynamicProxy,在我的IoC解析功能(Castle Windsor的一个小包装器)中我有以下代码:
T componenet = _container.Resolve<T>();
var gen = new ProxyGenerator();
if (typeof(T).IsClass)
{
return gen.CreateClassProxyWithTarget(componenet, _container.Resolve<StashInterceptor>());
}
else
{
return gen.CreateInterfaceProxyWithTarget(componenet, _container.Resolve<StashInterceptor>());
}
这也有效,而不是返回一个具体的类,它返回一个拦截函数调用并进行一些处理的代理,然后将调用转发给原来的具体类方法。
现在的问题是具体类中的事件没有侦听器(即使配置说它们也是这样)。
不确定这是在从代理调用方法时是否加载侦听器的错误或设计决定,但目前我正陷入困境,需要解决方案或解决方法。
有人有想法吗?
以下是我在web.config中的城堡xml配置:
<castle>
<facilities>
<facility id="event.wiring" type="Castle.Facilities.EventWiring.EventWiringFacility, Castle.Facilities.EventWiring" />
</facilities>
<components>
<component id="SomeInterceptor" type="Namespace.SomeInterceptor, MyAssembly" />
<component id="SomePublisher" type="Namespace.SomePublisher, MyAssembly">
<subscribers>
<subscriber id="SomeSubscriber" event="SomeEvent" handler="OnSomeEvent" />
</subscribers>
</component>
<component id="SomeSubscriber" type="Namespace.SomeSubscriber, MyAssembly" />
</components>
答案 0 :(得分:4)
注意:问题不是xml或流畅的配置,而是您自己通过Castle.DynamicProxy生成代理的事实。如果你改为利用容器并使用容器中的功能注册拦截器(顺便使用DynamicProxy),这将有效。
不确定您正在尝试做什么,但如下所示,使用侦听器注册拦截器并拦截侦听器方法调用并同时使用事件连接功能不是问题。这是windsor 3.3
public class EventWiringFacilityTests
{
public void RegisterInterceptorWithListenerAndMakeSureListenerSubscribes()
{
var container = new WindsorContainer();
container.AddFacility<EventWiringFacility>();
container.Register(Component.For<SomeInterceptor>());
container.Register(
Component.For<SimplePublisher>()
.PublishEvent(p => p.Event += null,
x => x.To<SimpleListener>("foo", l => l.OnEvent(null, null))),
Component.For<SimpleListener>().Interceptors<SomeInterceptor>().Named("foo"));
var someInterceptor = container.Resolve<SomeInterceptor>();
var simpleListener = container.Resolve<SimpleListener>();
Assert.That(simpleListener.EventHasHappened, Is.False);
var simplePublisher = container.Resolve<SimplePublisher>();
simplePublisher.Trigger();
Assert.That(simpleListener.EventHasHappened);
simpleListener.Snap();
Assert.That(someInterceptor.Intercepted);
}
}
public class SomeInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
Intercepted = true;
invocation.Proceed();
}
public bool Intercepted { get; set; }
}
public class SimplePublisher
{
public event EventHandler Event;
public void Trigger()
{
if (Event != null)
{
Event(this, new EventArgs());
}
}
}
public class SimpleListener
{
public bool EventHasHappened { get; set; }
public void OnEvent(object sender, EventArgs e)
{
EventHasHappened = true;
}
public virtual void Snap()
{
}
}