АОП с замком Виндзор
Я пытаюсь достичь АОП через атрибуты, используя перехватчики Castle Windsor. У меня был некоторый успех, но у меня были проблемы с аспектами на уровне класса по сравнению с уровнем метода.
- Если я использую только атрибуты уровня класса, все методы будут перехвачены.
- Если я использую только атрибуты уровня метода, эти методы будут перехвачены.
- Если я добавлю атрибут уровня класса и атрибут уровня метода, оба перехвата произойдут для методов, которые были приписаны, но те, которые не были, не будут перехвачены.
Итак, учитывая этот компонент:
public interface IMyComponent
{
void ShouldBeInterceptedByStopWatch_AND_ExceptionLogger();
void ShouldBeInterceptedByExceptionLogger();
}
[LogExceptionAspect]
public class MyComponent : IMyComponent
{
[StopwatchAspect]
public void ShouldBeInterceptedByStopWatch_AND_ExceptionLogger()
{
for (var i = 0; i < 2; i++) Thread.Sleep(1000);
}
public void ShouldBeInterceptedByExceptionLogger()
{
throw new NotImplementedException();
}
}
Я бы ожидал, что логгер перехватит ShouldBeInterceptedByExceptionLogger()
но этого не произойдет, пока я не удалю аспект секундомера из другого метода или не уберу аспект логгера из класса и не добавлю его в ShouldBeInterceptedByExceptionLogger()
, Но ShouldBeInterceptedByStopWatch_AND_ExceptionLogger()
перехватывается обоими.
Весь пример приложения можно найти по адресу - https://bitbucket.org/jayala/juggernet-aop
в основном то, что он делает, использует средство для регистрации IContributeComponentModelConstruction
это добавит перехватчик, если он найдет аспект на уровне класса, или добавит перехватчики метод +, если он найдет аспекты на уровне метода.
Вот как я загружаю контейнер:
var container = new WindsorContainer()
.AddFacility<LogExceptionAspectFacility>()
.AddFacility<StopwatchAspectFacility>()
.Register(Component
.For<IMyComponent>()
.ImplementedBy<MyComponent>()
.LifeStyle.Transient);
Что делает объект, так это регистрация перехватчика и участника модели, как это
public abstract class BaseAspectFacility<TAspectAttribute, TAspectInterceptor> : AbstractFacility
where TAspectAttribute : Attribute
where TAspectInterceptor : IInterceptor
{
protected override void Init()
{
var interceptorName = Guid.NewGuid().ToString();
Kernel.Register(Component.For<IInterceptor>()
.Named(interceptorName)
.ImplementedBy<TAspectInterceptor>()
.LifeStyle.Singleton);
var contributor = new ContributeAspectToModel<TAspectAttribute>(interceptorName);
Kernel.ComponentModelBuilder.AddContributor(contributor);
}
}