在学习.net core的过程中,我们已经明确被告知,Remoting将不会被支持。官方的解释是,.net framework 类型包含了太多的Runtime的内容,是一个非常重量级的服务实现,已被确定为一项有问题的体系结构。说白了就是迁移的难度很大,.net core中直接不提供了。
既然,.net core 已经不支持RealProxy,那么就只能另起炉灶了。通过翻阅.net core的代码,终于发现了一个程序集:System.Reflection.DispatchProxy。此程序中,有一个类型DispatchProxy。(灵感还是来自于WCF。WCF是.net 中重量级的API,微软不可能不支持,通过翻阅其中的实现逻辑,终于到了RealProxy的替代方案。)
通过DispatchProxy提供的功能,很容易可以替代RealProxy,Remoting的问题终于比较完美的解决了
.Net Core下使用DispatchProxy实现AOP实现动态代理////// 动态代理 /// public class MyDispatchProxy: DispatchProxy { private T Object { set; get; } public static T Create(Func creator) { object proxy = DispatchProxy.Create >(); ((MyDispatchProxy )proxy).Object = creator(); return (T)proxy; } /// /// 创建代理实例 T:所要代理的接口类型 TInterceptor:拦截器类型 /// /// 拦截器构造函数参数值 ///代理实例 public static T Create2(params object[] parameters) where TInterceptor : IDBHelper { var proxy = GetProxy(typeof(T)); ((MyDispatchProxy )proxy).CreateInstance(typeof(TInterceptor), parameters); return (T)proxy; } private static object GetProxy(Type targetType) { var callexp = Expression.Call(typeof(DispatchProxy), nameof(DispatchProxy.Create), new[] { targetType, typeof(MyDispatchProxy ) }); return Expression.Lambda >(callexp).Compile()(); } private void CreateInstance(Type interceptorType, object[] parameters) { var ctorParams = parameters.Select(x => x.GetType()).ToArray(); var paramsExp = parameters.Select(x => Expression.Constant(x)); var newExp = Expression.New(interceptorType.GetConstructor(ctorParams), paramsExp); this.Object = Expression.Lambda >(newExp).Compile()(); } protected override object Invoke(MethodInfo targetMethod, object[] args) { Write($"开始执行 DispatchProxy获取调用的方法的名称:{targetMethod.Name}"); var result = targetMethod.Invoke(Object, args); Write($"执行完成 DispatchProxy获取调用的方法的名称:{targetMethod.Name}"); return result; } public void Write(string msg) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine(msg); Console.ResetColor(); } }
System.Reflection.DispatchProxy只有一个Api,就是objecct Create
另外一个解决方案,就是用反射来构造这个泛型方法。
使用
class Program
{
static void Main(string[] args)
{
var userInfo = new UserInfo()
{
Account = "qq_27559331",
Password = "123456789",
UserName = "胡老汉"
};
//动态代理
var dBHelpe = MyDispatchProxy.Create(() => new MySqlDBHelper());
dBHelpe.Save(userInfo);
Console.WriteLine("****************************************");
IDBHelper dBHelper2 = MyDispatchProxy.Create(() => new DBHelper());
dBHelper2.Save(userInfo);
Console.WriteLine("rn使用Activator.CreateInstance()rn");
IDBHelper dBHelper3 = MyDispatchProxy.Create2();
dBHelper3.Save(userInfo);
Console.WriteLine("****************************************");
IDBHelper dBHelper4 = MyDispatchProxy.Create2();
dBHelper4.Save(userInfo);
Console.ReadKey();
}
}
控制台输出
.Net Framework 下Remoting核心类库RealProxy 实现AOP实现动态代理
再说迁移方案前,我们看看.net Framework中,使用Remoting的代码:通过Remoting核心类库RealProxy实现动态代理
////// 真实代理 /// ///public class MyRealProxy : RealProxy { private readonly T tTarget; public MyRealProxy(T target) : base(typeof(T)) { tTarget = target; } public override IMessage Invoke(IMessage msg) { IMethodCallMessage methodCallMessage = (IMethodCallMessage)msg; Write($"开始执行 RealProxy获取调用的方法的名称:{methodCallMessage.MethodName}"); object returnVaule = methodCallMessage.MethodBase.Invoke(this.tTarget, methodCallMessage.Args); ReturnMessage message = new ReturnMessage(returnVaule, new object[0], 0, null, (IMethodCallMessage)msg); Write($"执行完成 RealProxy获取调用的方法的名称:{methodCallMessage.MethodName}"); return message; } public void Write(string msg) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine(msg); Console.ResetColor(); } } /// /// 透明代理 /// public static class TransparentProxy { public static T Create(Func creator) { MyRealProxy realProxy = new MyRealProxy (creator()); T transparentProxy = (T)realProxy.GetTransparentProxy(); return transparentProxy; } public static T Create2 () { //使用Activator.CreateInstance ()创建类对象,类必须继承自MarshalByRefObject类或者 ContextBoundObject类 T instance = Activator.CreateInstance (); MyRealProxy realProxy = new MyRealProxy (instance); T transparentProxy = (T)realProxy.GetTransparentProxy(); return transparentProxy; } }
使用
class Program
{
static void Main(string[] args)
{
var userInfo = new UserInfo()
{
Account = "qq_27559331",
Password = "123456789",
UserName = "胡老汉"
};
IDBHelper dBHelper = TransparentProxy.Create(() => new MySqlDBHelper());
dBHelper.Save(userInfo);
Console.WriteLine("****************************************");
IDBHelper dBHelper2 = TransparentProxy.Create(() => new DBHelper());
dBHelper2.Save(userInfo);
Console.WriteLine("rn使用Activator.CreateInstance()rn");
IDBHelper dBHelper3 = TransparentProxy.Create2();
dBHelper3.Save(userInfo);
Console.WriteLine("****************************************");
IDBHelper dBHelper4 = TransparentProxy.Create2();
dBHelper4.Save(userInfo);
Console.ReadKey();
}
}
控制台输出,和.net core 使用 DispatchProxy效果一样的
注:使用的相关自定义类内容如下
public class UserInfo
{
public string Account { get; set; }
public string Password { get; set; }
public string UserName { get; set; }
}
public class DBHelper : MarshalByRefObject, IDBHelper
{
public int Save(UserInfo userInfo)
{
Console.WriteLine("数据SqlServer入库");
return default;
}
}
public class MySqlDBHelper : MarshalByRefObject, IDBHelper
{
public int Save(UserInfo userInfo)
{
Console.WriteLine("数据MySql入库");
return default;
}
}
public interface IDBHelper
{
int Save(UserInfo userInfo);
}



