使用.Net Remoting实现动态代理

本文通过C#实现了一个动态代理的示例,展示了如何通过创建真实代理类和透明代理,实现在不修改原有类的前提下动态修改其行为。具体步骤包括定义人物接口、实现学生类、创建真实代理类和透明代理,最终在控制台展示代理效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先写一个人物接口

public interface IUserProcessor
{
    string Name { get; set; }

    int Age { get; set; }

    void ShowMe();
}

然后写一个Student类实现该接口

/// <summary>
/// 这里需要同时继承MarshalByRefObject,否则无法动态生成
/// </summary>
public class Student : MarshalByRefObject, IUserProcessor
{
    public string Name { get; set; }
    public int Age { get; set; }

    public void ShowMe()
    {
        Console.WriteLine(ToString());
    }

    public override string ToString()
    {
        return $"大家好,我是{Name},我几年{Age}岁了";
    }
}

接着就是核心部分,通常也是固定的,我们需要一个真实代理类(RealProxyHelper<T>),并且是泛型的,这样任何一个类(必须继承MarshalByRefObject,所以要约束一下)我都可以传入并代理。最后要继承RealProxy

using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Proxies;

public class RealProxyHelper<T> : RealProxy where T : MarshalByRefObject
{
    public override IMessage Invoke(IMessage msg)
    {
        throw new NotImplementedException();
    }
}

之后,我们需要完善他

public class RealProxyHelper<T> : RealProxy
{
    /// <summary>
    /// 保存对象字段
    /// </summary>
    private readonly T target;

    /// <summary>
    /// 构造函数,需要调用父类构造方法
    /// </summary>
    /// <param name="_target"></param>
    public RealProxyHelper(T _target) : base(typeof(T))
    {
        target = _target;
    }

    /// <summary>
    /// 在方法执行前,做的一些事
    /// </summary>
    /// <param name="msg"></param>
    private void DoSomethingBefore(IMessage message)
    {
        Console.WriteLine("在方法执行前,做的一些事");
    }

    /// <summary>
    /// 在方法执行后,做的一些事
    /// </summary>
    /// <param name="message"></param>
    private void DoSomethinfAfter(IMessage message)
    {
        Console.WriteLine("在方法执行后,做的一些事");
    }


    /// <summary>
    /// 这里是要调用的方法
    /// </summary>
    /// <param name="msg"></param>
    /// <returns></returns>
    public override IMessage Invoke(IMessage msg)
    {
        //之前
        DoSomethingBefore(msg);

        //调用方法接口
        IMethodCallMessage callMessage = msg as IMethodCallMessage;

        //callMessage.MethodBase.Invoke 执行调用方法
        //target 对象
        //callMessage.Args 方法的参数数组
        //returnValue 方法的返回值
        object returnValue = callMessage.MethodBase.Invoke(target, callMessage.Args);

        //之后
        DoSomethinfAfter(msg);

        //返回调用方法的结果
        /* 参数:
           ret:
             从中生成当前 System.Runtime.Remoting.Messaging.ReturnMessage 实例的被调用方法所返回的对象。
           outArgs:
             作为 out 参数从被调用方法返回的对象。
           outArgsCount:
             从被调用方法返回的 out 参数的数目。
           callCtx:
             方法调用的 System.Runtime.Remoting.Messaging.LogicalCallContext。
           mcm:
             对被调用方法进行的原始方法调用。
        */
        return new ReturnMessage(returnValue, Array.Empty<object>(), 0, null, callMessage);
    }
}

最后一步我们需要一个透明代理

/// <summary>
/// 透明代理
/// </summary>
public static class TransparentProxy
{
    public static T Create<T>(IUserProcessor user) where T : MarshalByRefObject
    {
        //创建T实例
        T instance = user as T;
        RealProxyHelper<T> realProxy = new RealProxyHelper<T>(instance);
        //获取当前实例的透明代理GetTransparentProxy()返回object  需要一个强制转换
        T transparentProxy = realProxy.GetTransparentProxy() as T;
		
		//这里返回的就是被装饰好的T
        return transparentProxy;
    }
}

以上几乎都是固定的,我们需要修改的仅仅是public override IMessage Invoke(IMessage msg){}方法

现在,我们来开一下效果

static void Main(string[] args)
{
    IUserProcessor student = new Student
    {
        Age = 22,
        Name = "zxh"
    };

    student.ShowMe();
    Console.WriteLine("***************************");


    IUserProcessor newStudent = TransparentProxy.Create<Student>(student);
    newStudent.ShowMe();


    Console.Read();
}

在不修改User类的前提下, 我们实现了动态修改ShowMe方法
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值