I am currently trying to achieve AOP using Castle. I have created a .NET solution that takes care of the business (lets name it Project 1). I am thinking of creating a separate project that would house all of my AOP related classes (aspects) (This is named Project 2). My questions are :
1) Is it possible to use an xml configuration file in Project 1 to configure which aspects to apply during runtime? (I have a fair idea on the possibility of this, but let me know if its otherwise)
2) Is it possible to not touch the Project 1 (code change/rebuilding) for adding new aspects/ removing old aspects and have all of this governed via Project 2? Rephrasing, I do not want to change/build my business solution due to future additions or deletions of aspects.
You can configure components with XML (https://github.com/castleproject/Windsor/blob/master/docs/registering-components.md), this wouldn't require rebuild, also it is possible for project 2 to configure AOP, you can get project 1 to call out to project 2 to register the IOC services, from this point on you can register interceptors to act as aspects and apply them to any component you wish, project 2 will need to reference project 1 or the project which contains the interfaces and implementations that you wish to register these for.
example:
container.Register(
Component.For<LoggingInterceptor>().Lifestyle.Transient,
Component.For<CacheInterceptor>().Lifestyle.Transient,
Component.For<IOrderRepository>().ImplementedBy<OrderRepository>());
You would not have to change business code, you can register interceptors orthgonally, in project 2 you would reference the business project and register any custom interceptors against that interface. You can avoid xml configuration altogether and do it in project 2, you would rebuild project 2 drop it in, and restart the app. you can register interceptor with xml too (https://github.com/castleproject/Windsor/blob/master/docs/xml-registration-reference.md)
see section interceptor and proxy components section in https://github.com/castleproject/Windsor/blob/master/docs/registering-components.md, for xml configuratino of interceptors.
so for example:
Console App Project (references aop and business project)
static void Main(string[] args)
{
var container = IocContainerFactory.GetContainer();
ISomeBusinessService service = container.Kernel.Resolve<ISomeBusinessService>();
Console.WriteLine(service.ReturnSomething());
Console.ReadLine();
}
Business Project
public interface ISomeBusinessService
{
string ReturnSomething();
}
public class SomeBusinessService : ISomeBusinessService
{
public string ReturnSomething()
{
return "some business value from service";
}
}
AOP project (references business project)
public static class IocContainerFactory
{
public static IWindsorContainer GetContainer()
{
var container = new WindsorContainer();
container.Register(Component.For<IInterceptor>().ImplementedBy<TraceLoggingInterceptor>().LifestyleTransient());
container.Register(Component.For<ISomeBusinessService>().ImplementedBy<SomeBusinessService>().LifestyleTransient().Interceptors<TraceLoggingInterceptor>());
return container;
}
}
public class TraceLoggingInterceptor : IInterceptor
{
public void Intercept(IInvocation invocation)
{
Console.WriteLine("{0} - {1}", invocation.TargetType, invocation.Method);
invocation.Proceed();
}
}