如何在C#类中模拟WCF行为,实现方法调用前触发逻辑?
嘿,我来帮你搞定在普通C#类里模拟WCF那种「方法调用前触发自定义逻辑」的需求!其实核心就是实现AOP(面向切面编程)的方法拦截,和WCF里用自定义属性+调用器的思路本质是一样的,下面给你两种可行的实现方案:
模拟WCF前置触发逻辑的具体实现
1. 先定义你的自定义验证属性
首先把WCF里的属性逻辑迁移过来,让属性成为标记方法的“触发器”,并包含具体的验证逻辑:
/// <summary> /// 验证属性基类,标记方法需要执行前置验证 /// </summary> [AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = false)] public abstract class ValidationRequiredAttribute : Attribute { /// <summary> /// 执行前置验证的抽象方法,子类实现具体逻辑 /// </summary> /// <param name="methodInfo">当前被调用的方法信息</param> /// <param name="parameters">方法传入的参数</param> public abstract void Validate(MethodInfo methodInfo, object[] parameters); } /// <summary> /// 令牌验证的具体属性,继承基类实现验证逻辑 /// </summary> public class TokenValidationRequiredAttribute : ValidationRequiredAttribute { public override void Validate(MethodInfo methodInfo, object[] parameters) { // 这里写你的令牌验证逻辑——比如从参数里取令牌、校验签名等 Console.WriteLine($"正在对方法 {methodInfo.Name} 执行令牌验证..."); // 验证失败直接抛异常中断方法执行 // if (!IsTokenValid(parameters[0].ToString())) // throw new UnauthorizedAccessException("令牌无效,拒绝访问"); } }
2. 实现方法拦截逻辑
接下来需要一个“拦截器”,它会在调用目标方法前检查属性、执行验证。这里给你两种方案,一种是原生反射实现(不用额外依赖),另一种是用成熟的AOP库(更优雅)。
方案A:原生反射+包装类(零依赖)
自己写一个通用的服务包装类,手动处理反射和属性检查:
public class ServiceInterceptor<T> where T : class, new() { // 实际的业务服务实例 private readonly T _targetService = new T(); // 调用无返回值方法(简单版) public void CallMethod(string methodName, params object[] parameters) { var method = typeof(T).GetMethod(methodName) ?? throw new ArgumentException($"找不到方法 {methodName}"); // 执行所有标记的前置验证 RunPreValidation(method, parameters); // 调用目标方法 method.Invoke(_targetService, parameters); } // 调用有返回值方法(类型安全版,用表达式树解析方法) public TResult CallMethod<TResult>(Expression<Func<T, TResult>> methodExpression) { var methodCall = methodExpression.Body as MethodCallExpression ?? throw new ArgumentException("请传入合法的方法调用表达式"); var method = methodCall.Method; var parameters = methodCall.Arguments .Select(arg => Expression.Lambda(arg).Compile().DynamicInvoke()) .ToArray(); // 执行前置验证 RunPreValidation(method, parameters); // 执行方法并返回结果 return methodExpression.Compile()(_targetService); } // 提取公共的验证逻辑 private void RunPreValidation(MethodInfo method, object[] parameters) { var validationAttrs = method.GetCustomAttributes<ValidationRequiredAttribute>(true); foreach (var attr in validationAttrs) { attr.Validate(method, parameters); } } }
使用示例:
// 你的业务服务类,用属性标记需要验证的方法 public class MyBusinessService { [TokenValidationRequired] public void ProcessOrder(string token, Order order) { Console.WriteLine($"开始处理订单:{order.Id}"); } [TokenValidationRequired] public UserInfo GetUserInfo(string token, int userId) { return new UserInfo { Id = userId, Name = "张三" }; } } // 用拦截器调用服务方法 var interceptor = new ServiceInterceptor<MyBusinessService>(); // 调用无返回值方法 interceptor.CallMethod("ProcessOrder", "valid_token_123", new Order { Id = "ORD001" }); // 调用有返回值方法(类型安全) var user = interceptor.CallMethod(s => s.GetUserInfo("valid_token_123", 1001)); Console.WriteLine($"获取到用户:{user.Name}");
方案B:用Castle DynamicProxy(更优雅的AOP实现)
如果可以引入第三方库,Castle DynamicProxy能帮你省去手动写反射的麻烦,实现更简洁的拦截:
首先安装NuGet包:Install-Package Castle.Core
然后写拦截器类:
public class ValidationInterceptor : IInterceptor { public void Intercept(IInvocation invocation) { // 检查当前方法的验证属性并执行 var validationAttrs = invocation.Method.GetCustomAttributes<ValidationRequiredAttribute>(true); foreach (var attr in validationAttrs) { attr.Validate(invocation.Method, invocation.Arguments); } // 继续执行目标方法 invocation.Proceed(); } }
使用示例:
var proxyGenerator = new ProxyGenerator(); var interceptor = new ValidationInterceptor(); // 创建业务服务的代理对象 MyBusinessService serviceProxy = proxyGenerator.CreateClassProxy<MyBusinessService>(interceptor); // 直接调用方法就行,拦截器会自动触发前置验证 serviceProxy.ProcessOrder("valid_token_123", new Order { Id = "ORD002" }); var user = serviceProxy.GetUserInfo("valid_token_123", 1002); Console.WriteLine($"获取到用户:{user.Name}");
3. 和WCF机制的对比
WCF里是通过IOperationBehavior或者DispatchMessageInspector在消息处理管道中拦截方法调用,我们这里的实现核心思路完全一致:用属性标记需要拦截的方法→在方法执行前触发属性中的逻辑→再执行目标方法,完美模拟了WCF的行为。
内容的提问来源于stack exchange,提问作者Rafael León
相关产品推荐
相关产品推荐

