Search code examples
c#castle-windsorcastle-dynamicproxy

Caslte Windsor Proxy Generation Options


I've been struggling to find anything online, so I thought I'd see if anyone else knows how to sort this little issue I'm having.

I've got a scenario where I want to create a proxy object so that various other interfaces can be added to the same object. So far, I've not had any issues with this. One of my other requirements is to be able to set an attribute on the proxy-generated class.

I've been able to do this successfully using Castle DynmaicProxy manually, using something along the lines of:

var serviceOptions = new ProxyGenerationOptions();

// Create MyAttribute
var args = new object[] { "SomeName" };
var constructorTypes = new[] { typeof(String) };
var constructorInfo = typeof(MyAttribute).GetConstructor(constructorTypes);
var attributeBuilder = new CustomAttributeBuilder(constructorInfo, args);

serviceOptions.AdditionalAttributes.Add(attributeBuilder);

However, I'm using windsor to resolve my dependencies through injection. Windsor does provide some proxy options, such as:

configurer.Proxy.AdditionalInterfaces(interfaces);
configurer.Proxy.MixIns(r => r.Component(type));

But it does not seem to offer options for custom attributes. Does anyone know how this can be achieved? Many thanks.


Solution

  • The standard ProxyGroup provides access to a subset of the proxy generation options. However, it is relatively straight forward to create your own descriptor to modify other options and add it to the component registration. The trick is to use an extension method to retrieve the proxy options used by the built-in ProxyGroup registration helper.

    public class ProxyCustomAttributeBuilderDescriptor : IComponentModelDescriptor
    {
        public void BuildComponentModel(IKernel kernel, ComponentModel model)
        {
            var options = model.ObtainProxyOptions();    
            // ... do whatever you need to customise the proxy generation options
        }
    
        public void ConfigureComponentModel(IKernel kernel, ComponentModel model)
        {
        }
    }
    

    Then when you register your component simply add this descriptor:

    configurer.AddDescriptor(new ProxyCustomAttributeBuilderDescriptor());