如何获取无目标创建的Castle动态代理的接口类型
解决Castle DynamicProxy拦截器中识别代理目标接口的问题
方法一:直接检查代理实例的类型
Castle生成的代理类会直接实现你指定的目标接口,所以可以通过判断invocation.Proxy是否为目标接口的实例来区分:
public class Proxy : IInterceptor { public void Intercept(IInvocation invocation) { if (invocation.Proxy is IFoo) { // 当前代理基于IFoo生成 Console.WriteLine("处理IFoo代理的调用"); } else if (invocation.Proxy is IFooBase) { // 当前代理基于IFooBase生成 Console.WriteLine("处理IFooBase代理的调用"); } invocation.Proceed(); // 执行原方法逻辑 } }
这个方法简单直接,适配你的场景——IFoo继承自IFooBase,但IFooBase的代理不会实现IFoo,判断顺序不影响结果。
方法二:通过代理生成选项传递自定义标记
如果场景更复杂(比如多层接口继承、需要传递额外元数据),可以在创建代理时通过ProxyGenerationOptions附加自定义标记,再在拦截器中读取:
步骤1:定义自定义标记属性
[AttributeUsage(AttributeTargets.Class)] public class ProxyTargetInterfaceAttribute : Attribute { public Type TargetInterface { get; } public ProxyTargetInterfaceAttribute(Type targetInterface) { TargetInterface = targetInterface; } }
步骤2:创建代理时附加标记
var generator = new ProxyGenerator(); var proxy = new Proxy(); // 创建IFooBase代理 var optionsBase = new ProxyGenerationOptions(); optionsBase.SetCustomAttribute(new ProxyTargetInterfaceAttribute(typeof(IFooBase))); var fooBase = generator.CreateInterfaceProxyWithoutTarget<IFooBase>(optionsBase, proxy); // 创建IFoo代理 var optionsFoo = new ProxyGenerationOptions(); optionsFoo.SetCustomAttribute(new ProxyTargetInterfaceAttribute(typeof(IFoo))); var foo = generator.CreateInterfaceProxyWithoutTarget<IFoo>(optionsFoo, proxy);
步骤3:拦截器中读取标记
public class Proxy : IInterceptor { public void Intercept(IInvocation invocation) { var targetAttr = invocation.Proxy.GetType() .GetCustomAttribute<ProxyTargetInterfaceAttribute>(); if (targetAttr?.TargetInterface == typeof(IFoo)) { // 处理IFoo代理 } else if (targetAttr?.TargetInterface == typeof(IFooBase)) { // 处理IFooBase代理 } invocation.Proceed(); } }
这个方法更灵活,不依赖接口继承关系,适合多接口、复杂代理场景。
关键注意点
- 不要依赖
invocation.Method.DeclaringType:因为DoSomething定义在IFooBase中,无论代理基于哪个接口,这个属性都会返回IFooBase,这就是你之前遇到的核心问题。 - 避免依赖Castle内部代理类命名:比如
Castle.Proxies.IFooProxy这类命名属于内部实现,不同版本可能变化,稳定性差。
内容的提问来源于stack exchange,提问作者Mahdi
相关产品推荐
相关产品推荐

