#c# #castle-windsor #castle #castle-dynamicproxy
#c# #замок-Виндзор #castle #замок-DynamicProxy
Вопрос:
История началась так, я использовал средство 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>());
}
это также сработало, и вместо возврата конкретного класса он возвращает прокси, который перехватывает вызовы функций и выполняет некоторую обработку, а затем перенаправляет вызов на исходные методы конкретного класса.
проблема теперь в том, что события в конкретном классе не имеют прослушивателей (хотя в конфигурациях указано, что они есть).
не уверен, является ли это ошибкой или дизайнерским решением не загружать прослушиватели при вызове метода с прокси, но в настоящее время я в замешательстве и нуждаюсь в решении или обходном пути.
У кого-нибудь есть идея?
Вот мои конфигурации castle xml в web.config:
<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>
Ответ №1:
Примечание: проблема не в 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()
{
}
}
Комментарии:
1. Спасибо за ответ, но, похоже, со мной это не работает, я использую отображение xml, я отредактирую вопрос, чтобы показать вам свои конфигурации.