1

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.

user2930995
  • 63
  • 1
  • 4
  • 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 control 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. – BhavO Aug 04 '15 at 07:10
  • @BhavO - When you say that after registering the interceptors to act as aspects, we can apply them to any component (business methods), doesn't that mean that we would have to write some C# code in the business methods to apply that? And if we write anything in the business related project, that would require rebuilding. Am I interpreting it correctly or is there a way to not write anything in the business project and still achieve interception? – user2930995 Aug 04 '15 at 08:29
  • Also, http://stackoverflow.com/questions/31783755/configuring-castle-windsor-using-xml-app-config shows that my xml configuration is missing something and I am not able to use the xml configuration for registering interceptors. It would be great if you could also take a look there. – user2930995 Aug 04 '15 at 08:31
  • 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) – BhavO Aug 04 '15 at 08:51
  • see section interceptor and proxy components section in https://github.com/castleproject/Windsor/blob/master/docs/registering-components.md , for xml configuratino of interceptors – BhavO Aug 04 '15 at 08:58
  • @BhavO - Thanks :) Got it. I guess I would be ok with rebuilding the aspects project after doing registrations using fluent api and chuck xml config completely. Although it would be best to avoid rebuilds if I can manage the xml. – user2930995 Aug 04 '15 at 09:06

1 Answers1

1

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();
    }
}
BhavO
  • 2,406
  • 1
  • 11
  • 13
  • I quickly created two solutions on these lines and it did not work. The business operations, although registered for interception in the aspects project, were not intercepted. If you could create a quick PoC and share the findings, it would be great. I will have to unmark this as answer now. – user2930995 Aug 04 '15 at 10:00
  • is the business project using the container you have created in the aop project, also setting up interceptor is standard there are many samples online here is one http://blog.andreloker.de/post/2009/02/20/Simple-AOP-integrating-interceptors-into-Windsor.aspx , see end of artcile for download – BhavO Aug 04 '15 at 10:03
  • the creation and configuration of the container must happen in the aop project, the business project must reference the aop project to retreive the container, ie IOCContainerFactory.GetContainer() , this will be an entry point into the aop class for it create a container and register the business classes and interceptors, like in the example article: http://blog.devdave.com/2013/04/getting-started-with-castle-windsor.html – BhavO Aug 04 '15 at 10:06
  • I had seen these blogs earlier. Both articles are working within a single assembly. – user2930995 Aug 04 '15 at 10:28
  • yes for simplicity they have built example with one project, but you can spit part of the project out into a sepearte project and it will still work, this enables you to manage it as a seprate assembly (dll), and not have to modify the business dll. – BhavO Aug 04 '15 at 10:30
  • is the business project using the container you have created in the aop project? How do you achieve this? – user2930995 Aug 04 '15 at 10:31
  • it depends on your the composite root, is your app asp.net, winforms/wpf ?, if asp.net mvc for example your controllerfactory would call your aop project to get the container to resolve controllers (ie http://www.thebuttonfactory.nl/?p=1020) – BhavO Aug 04 '15 at 10:31
  • In that case you would call the an aop project class to get the container from which you would resolve the instance your interested in, for example IBussnessService b = AopProject.IOCContainerFactory.GetConainer(); in your main method, the IOCContainerFactory could be a static class, you would configure your container in the GetContainer method – BhavO Aug 04 '15 at 10:38
  • Could you elaborate with some code? Also, what would be the equivalent of IOCContainerFactory.GetConainer(); in Castle – user2930995 Aug 04 '15 at 11:01