普通代理:就是我们要知道嗲了的存在,然和才能访问;它要求就是客户端只能访问代理角色,而不能访问真实角色,这是比较简单的。
具体代码:
namespace ConsoleApplication1 { /// <summary> /// 游戏者接口 /// </summary> public interface IGamePlayer { //登录游戏 void Login(string user, string password); //杀怪 void killBoss(); //升级 void upgrade(); } /// <summary> /// 普通代理的游戏者 /// </summary> public class GamePlayer : IGamePlayer { private string name = ""; //构造函数限制谁能创建对象,并同时传递姓名 public GamePlayer(IGamePlayer _gamePlayer, string _name) { if (_gamePlayer == null) { throw new Exception("不能创建真实角色!"); } else { this.name = _name; } } public void Login(string user, string password) { Console.WriteLine("登录名为" + user + "的用户" + this.name + "登录成功!"); } public void killBoss() { Console.WriteLine(this.name + "在打怪!"); } public void upgrade() { Console.WriteLine(this.name + " 又升了一级!"); } } /// <summary> /// 普通代理的代理者 /// </summary> public class GamePlayerProxy: IGamePlayer { private IGamePlayer gamePlayer = null; //通过构造函数传递要对谁进行代练 public GamePlayerProxy(string name) { try { gamePlayer = new GamePlayer(this, name); } catch (Exception ex) { //TODO 异常处理 } } //代练登录 public void Login(string user, string password) { this.gamePlayer.Login(user, password); } //代练登录 public void killBoss() { this.gamePlayer.killBoss(); } //代练升级 public void upgrade() { this.gamePlayer.upgrade(); } } class Program { static void Main(string[] args) { //定义一个代理者 IGamePlayer proxy = new GamePlayerProxy("张三"); //开始打游戏,记下时间戳 Console.WriteLine(string.Format("开始时间是:{0}",DateTime.Now.ToString())); proxy.Login("zhangSan","password"); //开始杀怪 proxy.killBoss(); //升级 proxy.upgrade(); //记录结束游戏时间 Console.WriteLine(string.Format("结束时间是:{0}", DateTime.Now.ToString())); Console.ReadLine(); } } }
强制代理:只有通过真实角色指定的代理类才可以访问,换句话说 无法绕过代理访问到真实角色
具体代码:
namespace ConsoleApplication1 { /// <summary> /// 游戏者接口 /// </summary> public interface IGamePlayer { //登录游戏 void Login(string user, string password); //杀怪 void killBoss(); //升级 void upgrade(); //每个人都可以找一下自己的代理 IGamePlayer GetProxy(); } /// <summary> /// 强制代理的真实角色 /// </summary> public class GamePlayer : IGamePlayer { private string name = ""; //我的代理是谁 private IGamePlayer proxy = null; //构造函数限制谁能创建对象,并同时传递姓名 public GamePlayer(string _name) { this.name = _name; } public void Login(string user, string password) { if(this.isProxy()) Console.WriteLine("登录名为" + user + "的用户" + this.name + "登录成功!"); else Console.WriteLine("请使用指定的代理访问"); } public void killBoss() { if(this.isProxy()) Console.WriteLine(this.name + "在打怪!"); else Console.WriteLine("请使用指定的代理访问"); } public void upgrade() { if(this.isProxy()) Console.WriteLine(this.name + " 又升了一级!"); else Console.WriteLine("请使用指定的代理访问"); } //效验是否是代理访问 private bool isProxy() { return this.proxy==null? false:true; } //找到自己的代理 public IGamePlayer GetProxy() { this.proxy = new GamePlayerProxy(this); return this.proxy; } } /// <summary> /// 强制代理的代理者 /// </summary> public class GamePlayerProxy : IGamePlayer { private IGamePlayer gamePlayer = null; //通过构造函数传递要对谁进行代练 public GamePlayerProxy(IGamePlayer _gamePlayer) { this.gamePlayer=_gamePlayer; } //代练登录 public void Login(string user, string password) { this.gamePlayer.Login(user, password); } //代练登录 public void killBoss() { this.gamePlayer.killBoss(); } //代练升级 public void upgrade() { this.gamePlayer.upgrade(); } //代理的代理暂时还有,就是自己 public IGamePlayer GetProxy() { return this; } } class Program { static void Main(string[] args) { #region 对真实角色的访问(尝试绕开代理1) //定义一个代理者 IGamePlayer player1 = new GamePlayer("张三"); //开始打游戏,记下时间戳 Console.WriteLine(string.Format("开始时间是:{0}",DateTime.Now.ToString())); player1.Login("zhangSan", "password"); //开始杀怪 player1.killBoss(); //升级 player1.upgrade(); //记录结束游戏时间 Console.WriteLine(string.Format("结束时间是:{0}", DateTime.Now.ToString())); #endregion #region 直接访问代理类(尝试绕开非指定代理1) //定义一个游戏的角色 IGamePlayer player2 = new GamePlayer("张三"); //然后再定义一个代练者 IGamePlayer proxy2 = new GamePlayerProxy(player2); //开始打游戏,记下时间戳 Console.WriteLine(string.Format("开始时间是:{0}", DateTime.Now.ToString())); proxy2.Login("zhangSan", "password"); //开始杀怪 proxy2.killBoss(); //升级 proxy2.upgrade(); //记录结束游戏时间 Console.WriteLine(string.Format("结束时间是:{0}", DateTime.Now.ToString())); #endregion #region 访问指定代理(成功) //定义一个游戏的角色 IGamePlayer player3 = new GamePlayer("张三"); //然后再定义一个代练者 IGamePlayer proxy3 = player3.GetProxy(); //开始打游戏,记下时间戳 Console.WriteLine(string.Format("开始时间是:{0}", DateTime.Now.ToString())); proxy3.Login("zhangSan", "password"); //开始杀怪 proxy3.killBoss(); //升级 proxy3.upgrade(); //记录结束游戏时间 Console.WriteLine(string.Format("结束时间是:{0}", DateTime.Now.ToString())); #endregion Console.ReadLine(); } } }
.Net 动态代理,AOP
DynamicAction 动态代理要执行的方法
using System; namespace ConsoleApp { /// <summary> /// 动态代理要执行的方法 /// </summary> public class DynamicAction { /// <summary> /// 执行目标方法前执行 /// </summary> public Action BeforeAction { get; set; } /// <summary> /// 执行目标方法后执行 /// </summary> public Action AfterAction { get; set; } } }
动态代理类
using System; using System.Collections.Generic; using System.Runtime.Remoting; using System.Runtime.Remoting.Messaging; using System.Runtime.Remoting.Proxies; namespace ConsoleApp { /// <summary> /// 动态代理类 /// </summary> /// <typeparam name="T"></typeparam> public class DynamicProxy<T> : RealProxy { private readonly T _targetInstance = default(T); public Dictionary<string, DynamicAction> ProxyMethods { get; set; } public DynamicProxy(T targetInstance) : base(typeof(T)) { _targetInstance = targetInstance; } public override IMessage Invoke(IMessage msg) { var reqMsg = msg as IMethodCallMessage; if (reqMsg == null) { return new ReturnMessage(new Exception("调用失败!"), null); } var target = _targetInstance as MarshalByRefObject; if (target == null) { return new ReturnMessage(new Exception("调用失败!请把目标对象 继承自 System.MarshalByRefObject"), reqMsg); } var methodName = reqMsg.MethodName; DynamicAction actions = null; if (ProxyMethods != null && ProxyMethods.ContainsKey(methodName)) { actions = ProxyMethods[methodName]; } if (actions != null && actions.BeforeAction != null) { actions.BeforeAction(); } var result = RemotingServices.ExecuteMessage(target, reqMsg); if (actions != null && actions.AfterAction != null) { actions.AfterAction(); } return result; } } }
代理工厂
using System.Collections.Generic; namespace ConsoleApp { /// <summary> /// 代理工厂 /// </summary> /// <typeparam name="T"></typeparam> public class ProxyFactory<T> { public static T Create(T obj, Dictionary<string, DynamicAction> proxyMethods = null) { var proxy = new DynamicProxy<T>(obj) { ProxyMethods = proxyMethods }; return (T)proxy.GetTransparentProxy(); } } }
User
using System; namespace ConsoleApp { public class User : MarshalByRefObject { public int Age { get; set; } public string Name { get; set; } public bool Add(string name, int age, out int count) { Name = name; Age = age; count = 1; Console.WriteLine("Add " + Name + " ..."); return true; } public string SayName() { Console.WriteLine("My name is " + Name); return Name; } } }
Main
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApp { class Program { static void Main(string[] args) { var proxyMotheds = new Dictionary<string, DynamicAction>(); // key is Proxy's methodName, value is Actions proxyMotheds.Add("Add", new DynamicAction() { BeforeAction = new Action(() => Console.WriteLine("Before Doing....")), AfterAction = new Action(() => Console.WriteLine("After Doing....")) }); var user = new User(); //proxy for User var t = ProxyFactory<User>.Create(user, proxyMotheds); int count = 0; t.Add("Tom", 28, out count); t.SayName(); Console.WriteLine(count); Console.Read(); } } }