Castle Windsor 代理生成选项

Caslte Windsor Proxy Generation Options

我一直在努力在网上找到任何东西,所以我想看看是否有其他人知道如何解决我遇到的这个小问题。

我有一个场景,我想创建一个代理对象,以便可以将各种其他接口添加到同一对象。到目前为止,我对此没有任何问题。我的其他要求之一是能够在代理生成的 class.

上设置属性

我已经能够手动使用 Castle DynmaicProxy 成功地做到这一点,使用的是:

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);

但是,我正在使用 windsor 通过注入解决我的依赖关系。 Windsor确实提供了一些代理选项,例如:

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

但它似乎没有提供自定义属性的选项。有谁知道这是如何实现的?非常感谢。

标准 ProxyGroup 提供对代理生成选项子集的访问。但是,创建您自己的描述符以修改其他选项并将其添加到组件注册中是相对直接的。诀窍是使用扩展方法来检索内置 ProxyGroup 注册助手使用的代理选项。

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)
    {
    }
}

然后当你注册你的组件时,只需添加这个描述符:

configurer.AddDescriptor(new ProxyCustomAttributeBuilderDescriptor());

最后,我从 Phil 的想法和扫描 Castle 源代码中找到了替代解决方案。

我创建了一个自定义 ProxyFactory class,它扩展了 Castle.Windsor 程序集的 DefaultProxyFactory。我实现的唯一方法是 CustomizeOptions 方法,默认情况下它是空的。

从这里,我连接到 ComponentModelExtendedProperties 以获取我在注册组件时添加的 CustomAttributeBuilder 个实例的集合。

完整代码如下:

internal const string PROXY_ATTRIBUTES_PROPERTY_KEY = "custom.proxy.attributes";

protected override void CustomizeOptions(ProxyGenerationOptions options, IKernel kernel, ComponentModel model, object[] arguments)
{
    if (model.ExtendedProperties.Contains(PROXY_ATTRIBUTES_PROPERTY_KEY))
    {
        var proxyAttributes = (IEnumerable<CustomAttributeBuilder>)model.ExtendedProperties[PROXY_ATTRIBUTES_PROPERTY_KEY];
        foreach (var attribute in proxyAttributes)
        {
            options.AdditionalAttributes.Add(attribute);
        }
    }

    base.CustomizeOptions(options, kernel, model, arguments);
}

configurer.ExtendedProperties(new Property(CustomProxyFactory.PROXY_ATTRIBUTES_PROPERTY_KEY, configurator.ProxySettings.CustomAttributes));