views:

352

answers:

1

Hi, I've got a bit of a problem. I'm working in the Caste Windsor IOC Container. Now what i wanted to do is just mess about with some AOP principles and what i specifically want to do is based on a method name perform some logging. I have been looking at Interceptors and at the moment i am using the IInterceptor interface implemented as a class to perform this logging using aspects. The issue is if i want to perform the logging on a specific method then it gets messy as i need to put in some logic into my implemented aspect to check the method name etc...

I have read that you can do all of this using Dynamic Proxies and the IInterceptorSelector interface and the IProxyGenerationHook interface. I have seen a few examples of this done on the net but i am quite confused how this all fits into the Windsor container. I mean i am using the windsor container which in my code is actually a ref to the IWindsorContainer interface to create all my objects. All my configuration is done in code rather than XML.

Firstly does anyone know of a way to perform method specific AOP in the windsor container besides the way i am currently doing it.

Secondly how do i use the Dynamic Proxy in the windsor container ?

Below i have added the code where i am creating my proxy and registering my class with the interceptors

        ProxyGenerator _generator = new ProxyGenerator(new PersistentProxyBuilder());
        IInterceptorSelector _selector = new CheckLoggingSelector();
        var loggingAspect = new LoggingAspect();
        var options = new ProxyGenerationOptions(new LoggingProxyGenerationHook()) { Selector = _selector };
        var proxy = _generator.CreateClassProxy(typeof(TestClass), options, loggingAspect);
        TestClass testProxy = proxy as TestClass;

        windsorContainer.Register(
        Component.For<LoggingAspect>(),
        Component.For<CheckLoggingAspect>(),
        Component.For<ExceptionCatchAspect>(),
        Component.For<ITestClass>()
            .ImplementedBy<TestClass>()
            .Named("ATestClass")
            .Parameters(Parameter.ForKey("Name").Eq("Testing"))
            .Proxy.MixIns(testProxy));

The Test Class is below:

public class TestClass : ITestClass
{
    public TestClass()
    {

    }        

    public string Name
    {
        get;
        set;
    }
    public void Checkin()
    {
        Name = "Checked In";
    }
}

as for the interceptors they are very simple and just enter a method if the name starts with Check.

Now when i resolve my TestClass from the container i get an error.

{"This is a DynamicProxy2 error: Mixin type TestClassProxy implements IProxyTargetAccessor which is a DynamicProxy infrastructure interface and you should never implement it yourself. Are you trying to mix in an existing proxy?"}

I know i'm using the proxy in the wrong way but as i haven't seen any concrete example in how to use a proxy with the windsor container it's kind of confusing.

I mean if i want to use the LoggingProxyGenerationHook which just tell the interceptors to first for methods that start with the word "check" then is this the correct way to do it or am i completely on the wrong path. I just went down the proxy way as it seems very powerfull and i would like to understand how to use these proxies for future programming efforts.

Thanks a lot.

+2  A: 

By using .Interceptors() you already are using Dynamic Proxy. When component has specified interceptors Windsor will create proxy for it, and use these interceptors for it. You can also use method .SelectedWith and .Proxy property to set other options you already know from DynamicProxy.

I just added a website about Windsor AOP to documentation wiki. There's not much there yet, but I (and Mauricio ;) ) will put there all the information you need. Take a look, and let us know if everything is clear, and if something is missing.

Krzysztof Koźmic
Thanks for that.I'm not sure if i have done this correctly but i first declared a new proxy and set it up for use with my test class by adding it in usng the Proxy.MixIns(..) method. Now the class registers succesfully but when i try to resolve it from the container i get an error as shown:{"This is a DynamicProxy2 error: Mixin type TestClassProxy implements IProxyTargetAccessor which is a DynamicProxy infrastructure interface and you should never implement it yourself. Are you trying to mix in an existing proxy?"}How can i attach a new proxy to the class registration ?
Iffy
well I see the exception error pretty much says it all, doesn't it?Your service is the proxy. By the virtue of marking it as having mixins, interceptors and such, you make it a proxy. So you don't mix in an existing proxy to a component you want to proxy, because then you end up with this error. Is that any clear? Show me the code.
Krzysztof Koźmic
Hi, I have ammended my question to include the simplest of code, i have stripped out all the other registration stuff and just left one class where i am trying to attach the proxy. This proxy stuff really does confuse me for some reason.Thanks a lot.Iffy
Iffy