C# Castle DynamicProxy中断事件连接侦听器
故事是这样开始的,我使用Castle EventWiring工具来定义类中事件的侦听器,它工作得很好,我经常引发这样的事件:C# Castle DynamicProxy中断事件连接侦听器,c#,castle-windsor,castle,castle-dynamicproxy,C#,Castle Windsor,Castle,Castle Dynamicproxy,故事是这样开始的,我使用Castle EventWiring工具来定义类中事件的侦听器,它工作得很好,我经常引发这样的事件: if (null != BlaBlaEvent) { BlaBlaEvent(someData); } 最近我遇到了一个业务需求,我认为最好的解决方案可能是使用代理模式,所以我使用了DynamicProxy,在我的IoC解析函数(Castle Windsor的一个小包装器)中,我有以下代码: T componenet = _container.Resolve&l
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>());
}
T componenet=\u container.Resolve();
var gen=新的ProxyGenerator();
if(类型(T).IsClass)
{
返回gen.CreateClassProxyWithTarget(componenet,_container.Resolve());
}
其他的
{
返回gen.createInterfaceProxy和target(componenet,_container.Resolve());
}
这也起到了作用,它不返回具体类,而是返回一个代理,该代理截获函数调用并进行一些处理,然后将调用转发给原始的具体类方法
现在的问题是,具体类中的事件没有侦听器(即使配置说它们有)
不确定这是一个bug还是一个在从代理调用方法时不加载侦听器的设计决策,但目前我有点困惑,需要一个解决方案或解决方法
有人有主意吗
以下是我在web.config中的castle 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>
注意:问题不在于xml或fluent配置,而在于您正在通过Castle.DynamicProxy自己生成代理。如果您转而利用容器并使用容器中的功能注册拦截器(顺便说一句,它使用DynamicProxy),这将起作用 不确定您到底想做什么,但如下所示,向侦听器注册一个侦听器并让它侦听侦听器方法调用,同时使用事件连接功能并不是问题。这是温莎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()
{
}
}
公共类事件wiringfacilityTests
{
具有ListenerAndMakeSureListenerSubscribes()的公共无效RegisterInterceptor
{
var container=新的WindsorContainer();
container.AddFacility();
container.Register(Component.For());
集装箱。登记(
用于()的组件
.PublishEvent(p=>p.Event+=null,
x=>x.To(“foo”,l=>l.OnEvent(null,null)),
Component.For().Interceptors().Named(“foo”);
var someInterceptor=container.Resolve();
var simpleListener=container.Resolve();
Assert.That(simpleListener.eventhashappen,Is.False);
var simplePublisher=container.Resolve();
simplePublisher.Trigger();
Assert.That(simpleListener.eventhashappen);
simpleListener.Snap();
Assert.That(someInterceptor.Intercepted);
}
}
公共类侦听器:IInterceptor
{
公共无效拦截(IInvocation调用)
{
拦截=真;
invocation.procedure();
}
截获的公共布尔{get;set;}
}
公共类SimplePublisher
{
公共事件处理程序事件;
公共无效触发器()
{
如果(事件!=null)
{
事件(此,新的EventArgs());
}
}
}
公共类SimpleListener
{
公共bool eventhashappen{get;set;}
public void OnEvent(对象发送方,事件参数)
{
eventhashappen=true;
}
公共虚拟空间快照()
{
}
}
Thanx的回复,但它似乎不适合我,我使用xml映射,我将编辑问题以向您显示我的配置。