Search code examples
inversion-of-controlcastle-windsordecoratorcastle-dynamicproxy

Using DynamicProxy as a decorator pattern in windsor container


I am looking for some info on using and configuring windsor to provide a dynamic proxy to intercept calls to an instance of another class.

My class represents a resource that should be retained as a long lived instance by the container for performance reasons. However, sometimes this resource can transition into ununusable state, and requires renewing. I would like the container to handle this so client code doesn't have to. I can create my own factory to do this, I would like to know if there is some Windsor registration coolness to do it for me so I don't have to create the separate factory class :)

Here is some pseudo code to demonstrate the problem:

public interface IVeryImportantResource
{
    void SomeOperation();
}

public class RealResource : IVeryImportantResource
{
    public bool Corrupt { get; set; }

    public void SomeOperation()
    {
        //do some real implementation
    }
}

public class RealResourceInterceptor : IInterceptor
{
    private readonly IKernel kernel;

    public RealResourceInterceptor(IKernel Kernel)
    {
        kernel = Kernel;
    }

    public void Intercept(IInvocation invocation)
    {
        RealResource resource = invocation.InvocationTarget as RealResource;

        if(resource.Corrupt)
        {
            //tidy up this instance, as it is corrupt
            kernel.ReleaseComponent(resource);
            RealResource newResource = kernel.Resolve<RealResource>(); //get a new one
            //now what i would like to happen is something like this
            //but this property has no setter, so this doesn't work
            //also, i would like to know how to register RealResourceInterceptor as well RealResourceInterceptor
            invocation.InvocationTarget = newResource;
        }
        invocation.Proceed();
    }
}

Any ideas how to implement something like my RealResourceInterceptor class, and also how to configure the container to use it? Thanks!


Solution

  • This question is more about renewing a singleton component than interception. The problem of renewing singletons is answered in this question.

    Bottom line: it's not as easy as it seems, there are many pitfalls with this approach.

    Maybe the problem lies in this component getting corrupted (why does this happen?)