一 Attribute原理:
Attribute注解,是附加上方法、属性、类等上面的标签,
可以通过方法的GetCustomAttribute获得粘贴的这个Attribute对象
通过反射调用到粘贴到属性、方法、类等等的对象
任务:改造ORM
ORM约定:类得名字与表的名字一样,主键必须是Id,
改造一下ORM(类名还可以和表名不一样,Id可以与主键不一样)
//在sayHello方法的描述信息MethodInfo上粘了一个RupengAttribute对象
//注解的值必须是常量,不能是动态算出来的 [RupengAttribute(Name=DateTime.Now.ToString())]
//[RupengAttribute(Name="rupengwnag")]
//一般特性Attribute的类名都以Attribute结尾,这样用的时候就不用谢"Attribute"了
二 Attribute步骤:
1 Attribute本身类
2 标记了Attribute的类
3 通过找到这个类的Attribute标记,从而先去执行上面的Attribute类
三 Attribute示例:
//testAttribute.csProj
namespace testAttribute { class Program { static void Main(string[] args) { Type type = typeof(Person); //1 获得SayHello()上的Attribute注解对象 object[] objs = type.GetMethod("SayHello").GetCustomAttributes(typeof(AlibabaAttribute), true); foreach(object obj in objs) { AlibabaAttribute ali = obj as AlibabaAttribute; Console.WriteLine(ali.Name); } //2 在类中的方法中找到Obsolete注解对象 MethodInfo[] methods = type.GetMethods(); foreach(MethodInfo method in methods) { Object[] obsols = method.GetCustomAttributes(typeof(ObsoleteAttribute),true); if (obsols.Length>0) { ObsoleteAttribute obsol = obsols[0] as ObsoleteAttribute; Console.WriteLine("不能执行该方法:" + obsol.Message); } } //3 获得Love()的Attribute注解对象 object[] objtens = type.GetMethod("Love").GetCustomAttributes(typeof(TengxunAttribute), true); foreach (object obj in objtens) { TengxunAttribute ten = obj as TengxunAttribute; Console.WriteLine(ten.Name); } Console.ReadKey(); } } class Person { [Alibaba(Name="阿里人是幸福的")] public void SayHello() { } [Obsolete("这个方法已过时,禁止访问")] public void F1() { } [Tengxun(Name = "腾讯是我的最爱")] public void Love() { } } //1 [AttributeUsage(AttributeTargets.Method)] class AlibabaAttribute : Attribute { public AlibabaAttribute() { } public AlibabaAttribute(string name) { this.Name = name; } public string Name { get; set; } } //2 class TengxunAttribute : Attribute { public string Name { get; set; } } }
四 Attribute应用:
当执行某个action方法时,先获得Attribute对象,用于检查权限
//PermissionActionAttribute.cs
/// <summary> /// 权限动作的 Attribute注解 /// </summary> [AttributeUsage(AttributeTargets.Method)] public class PermissionActionAttribute:Attribute { public string Name { get; set; } public PermissionActionAttribute(string name) { this.Name = name; } }
//BaseController.cs
public class BaseController : IHttpHandler, IRequiresSessionState { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/html"; //需要约定方法:public void list(HttpContext context) //方法名和action一致 #region 检查用户是否登录 LoginHelper.CheckHasLogin(context); #endregion string action = context.Request["action"]; if(action==null) { throw new Exception("未找到action:"+action); } Type type = this.GetType(); //this是被new的对象,即子类CategoryController等 //try //{ MethodInfo method = type.GetMethod(action); #region /获得该action的 Attribute注解对象 //获得action该方法的 Attribute注解对象(注解对象的Name属性就是权限的名称,用于判断权限) object[] objAttrs = method.GetCustomAttributes(typeof(PermissionActionAttribute), true); if (objAttrs.Length > 0) { PermissionActionAttribute paa = objAttrs[0] as PermissionActionAttribute; AdminHelper.CheckHasPower(context, paa.Name); } #endregion method.Invoke(this, new object[] { context }); //调用this对象的method方法 (参数列表是object[],其中一个参数是context) //} //catch(Exception ex) //如果找不到这个action方法,就说明这个action是错误的/不存在的 //{ // throw new Exception("未知的action:"+action); //} } public bool IsReusable { get { return true; } } }
//CourseController.cs
[PermissionAction("新增课程")] public void addnew(HttpContext context) { #region 新增展示 string categoryidStr = context.Request["categoryid"]; int categoryid = VolidHelper.CheckStrToInt(categoryidStr); TD_COURSE course = new TD_COURSE(); course.VIDEOCATEGORYID = categoryid; RazorHelper.RazorParse(context, "~/Course/CourseAlter.cshtml", new { action = "addnew", course = course }); #endregion }