.Net里的Attribute 学习
前两天看到书里边讲Attribute定制,结合了网上的资料,自己做了简单的登录功能,并结合了某些设计模式,有兴趣的朋友可以看下。由于时间原因,没有做过多的说明,直接上代码,希望能帮助哪些不会的初学者,同时也希望得到高人的指点,本人将虚心接受批评,谢谢!
用户登录操作类:
View Code
using System; using LemonFreamworkAOP.User; using LemonFreamworkAOP.AOP; namespace LemonFreamworkAOP.User { [LoginAOP] public class UserDAL : ContextBoundObject, IUser { private UserInfo userInfo; public UserDAL(UserInfo userInfo) { this.userInfo = userInfo; } public Boolean IsLogin(UserInfo user) { return this.userInfo == user; } } }
下边是几个核心抽象基类类:
AOPProperty
using System; using System.Runtime.Remoting.Activation; using System.Runtime.Remoting.Contexts; using System.Runtime.Remoting.Messaging; namespace LemonFreamworkAOP.AOP { public abstract class AOPProperty : IContextProperty, IContributeObjectSink { protected virtual String GetName { get { return "AOP"; } } protected virtual Boolean IsOK(Context newCtx) { return true; } protected abstract IMessageSink GetSink(IMessageSink nextSink); #region IContextProperty IContributeObjectSink public void Freeze(Context newContext) { } public Boolean IsNewContextOK(Context newCtx) { return IsOK(newCtx); } public String Name { get { return GetName; } } public IMessageSink GetObjectSink(MarshalByRefObject obj, IMessageSink nextSink) { return GetSink(nextSink); } #endregion } }
AOPAttribute
using System; using System.Runtime.Remoting.Activation; using System.Runtime.Remoting.Contexts; using System.Runtime.Remoting.Messaging; namespace LemonFreamworkAOP.AOP { public abstract class AOPAttribute : ContextAttribute { public AOPAttribute() : base("AOP") { } public sealed override void GetPropertiesForNewContext(IConstructionCallMessage ctorMsg) { ctorMsg.ContextProperties.Add(CreateAOPProperty()); } protected abstract AOPProperty CreateAOPProperty(); } }
AOPSink
using System; using System.Collections.Generic; using LemonFreamworkAOP.User; using System.Runtime.Remoting.Activation; using System.Runtime.Remoting.Contexts; using System.Runtime.Remoting.Messaging; namespace LemonFreamworkAOP.AOP { public abstract class AOPSink : IMessageSink { private Dictionary<String, Object> beforeHandles; private Dictionary<String, Object> afterHandler; private IMessageSink messageSink; protected const String errorDesc = "Not Find MethodName !"; public AOPSink(IMessageSink messageSink) { this.beforeHandles = new Dictionary<String, Object>(); this.afterHandler = new Dictionary<String, Object>(); this.messageSink = messageSink; AddAllBeforeAOPHandle(); AddAllAfterAOPHandle(); } public virtual void AddBeforeAOPHandle(String methodName, BeforeAOPHandle beforeHandle) { if (String.IsNullOrEmpty(methodName)) return; if (!beforeHandles.ContainsKey(methodName)) beforeHandles.Add(methodName, beforeHandle); } public virtual void AddAfterAOPHandle(String methodName, AfterAOPHandle aftereHandle) { if (String.IsNullOrEmpty(methodName)) return; if (!afterHandler.ContainsKey(methodName)) afterHandler.Add(methodName, aftereHandle); } public virtual BeforeAOPHandle FindBeforeAOPHandle(String methodName) { if (beforeHandles.ContainsKey(methodName)) return beforeHandles[methodName] as BeforeAOPHandle; else throw new Exception(errorDesc); } public virtual AfterAOPHandle FindAfterAOPHandle(String methodName) { if (afterHandler.ContainsKey(methodName)) return beforeHandles[methodName] as AfterAOPHandle; else throw new Exception(errorDesc); } public IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink) { return null; } public IMessageSink NextSink { get { return this.messageSink; } } public IMessage SyncProcessMessage(IMessage msg) { IMethodCallMessage callMsg = msg as IMethodCallMessage; BeforeProcess(callMsg); IMessage imsg = messageSink.SyncProcessMessage(msg); //IMethodReturnMessage retMsg = imsg as IMethodReturnMessage; //AfterProcess(callMsg.MethodName, retMsg); return imsg; } protected abstract void AddAllBeforeAOPHandle(); protected abstract void AddAllAfterAOPHandle(); protected virtual void BeforeProcess(IMethodCallMessage callMsg) { String methodName = callMsg.MethodName; BeforeAOPHandle beforeHandle = FindBeforeAOPHandle(methodName); if (beforeHandle != null) beforeHandle(callMsg); } protected virtual void AfterProcess(String methodName, IMethodReturnMessage retMsg) { AfterAOPHandle afterHandle = FindAfterAOPHandle(methodName); if (afterHandle != null) afterHandle(retMsg); } } }
以下是登录功能的派生子类
LoginAOPAttribute
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace LemonFreamworkAOP.AOP { [AttributeUsage(AttributeTargets.Class)] public class LoginAOPAttribute : AOPAttribute { protected override AOPProperty CreateAOPProperty() { return new LoginAOPProperty(); } } }
LoginAOPProperty
using System; using System.Runtime.Remoting.Activation; using System.Runtime.Remoting.Contexts; using System.Runtime.Remoting.Messaging; namespace LemonFreamworkAOP.AOP { public class LoginAOPProperty : AOPProperty { protected override IMessageSink GetSink(IMessageSink nextSink) { return new LoginAOPSink(nextSink); } } }
LoginAOPSink
using System; using LemonFreamworkAOP.User; using LemonFreamworkAOP.Untity; using System.Runtime.Remoting.Activation; using System.Runtime.Remoting.Contexts; using System.Runtime.Remoting.Messaging; namespace LemonFreamworkAOP.AOP { public class LoginAOPSink : AOPSink { public LoginAOPSink(IMessageSink messageSink) : base(messageSink) { } public void BeforeUserLogin(IMethodCallMessage callMsg) { UserInfo loginUser = callMsg.GetArg(0) as UserInfo; UserInfo configUser = ConfigHelper.GetUser; if (loginUser.UserName != configUser.UserName || loginUser.Password != configUser.Password) throw new Exception("用户名或密码不正确!"); } protected override void AddAllBeforeAOPHandle() { AddBeforeAOPHandle("IsLogin", BeforeUserLogin); } protected override void AddAllAfterAOPHandle() { } } }
分类: CLR Via C#