1.先做个小例子
特性,只能通过反射实现
我们自定义一个特性
public class CustomAttribute : Attribute
{
public int Id;
public string Name;
public string Reamrk;
public string Desc;
public CustomAttribute() : this(0, "") { }//如果没传参,使用this给默认值
public CustomAttribute(int \_id, string \_name)
{
this.Id = \_id;
this.Name = \_name;
}
public void Show()
{
Console.WriteLine($"{Id}\_{Name}\_{Reamrk}\_{Desc}");
}
}
写一个类并注册特性
\[Custom(123,"kxy",Desc ="是个帅哥",Reamrk ="学员")\]
public class Student
{
\[Custom(124, "wzz", Desc = "是个丑逼", Reamrk = "学员")\]
public void Study()
{
Console.WriteLine($"正在学习");
}
}
实现特性调用,只能通过反射,没办法和MVC那样直接调用接口特性就会执行(因为MVC已经封装好了调用的反射机制)
class Program
{
static void Main(string\[\] args)
{
Student student = new Student();
Type type = student.GetType();
// 判断该类是否注册了CustomAttribute
if (type.IsDefined(typeof(CustomAttribute), true))
{
var attribute = type.GetCustomAttribute<CustomAttribute>();
attribute.Show();
}
MethodInfo method = type.GetMethod("Study");
// 判断该方法是否注册了CustomAttribute
if (method.IsDefined(typeof(CustomAttribute), true))
{
var attribute = method.GetCustomAttribute<CustomAttribute>();
attribute.Show();
}
// 执行了特性之后执行方法
student.Study();
Console.ReadLine();
}
}
结果:
由上可知,执行步骤先是执行类注册、在是方法注册的特性,然后再是执行我们需要的方法
这个思路和MVC 提供的特性是一致的
2.MVC特性思路
先定义三大特性
namespace Study.CustomMVCAttribute.CustomMVCAttribute
{
///
public class FilterAttribute : Attribute { }
///
public class AuthorizeAttribute : FilterAttribute
{
public void OnAuthorization()
{
Console.WriteLine("OnAuthorization");
}
}
///
public class ActionFilterAttribute : FilterAttribute
{
public void OnActionExecuting()
{
Console.WriteLine("OnActionExecuting");
}
public void OnActionExecuted()
{
Console.WriteLine("OnActionExecuted");
}
// OnResultExecuting 和 OnResultExecuted 先不管
}
///
public class HandleErrorAttribute : FilterAttribute
{
public void OnException()
{
Console.WriteLine("OnException");
}
}
}
定义 ControllerActionInvoker
using System;
using System.Linq;
using System.Reflection;
namespace Study.CustomMVCAttribute.CustomMVCAttribute
{
public class ControllerActionInvoker
{
///
/// 调用的实例
/// 方法名
/// 参数
public static void InvokeAction(object instance, string action, object[] parameters = null)
{
Type type = instance.GetType();
MethodInfo method = type.GetMethod(action);
if (method.IsDefined(typeof(FilterAttribute), true))
{
var filterList = method.GetCustomAttributes
try
{
// 授权
AuthorizeAttribute authorize = (AuthorizeAttribute)filterList.FirstOrDefault(v => v is AuthorizeAttribute);
if (authorize != null)
{
authorize.OnAuthorization();
}
// 方法执行前
var actionList = filterList.Where(v => v is ActionFilterAttribute);
foreach (var item in actionList)
{
((ActionFilterAttribute)item).OnActionExecuting();
}
// 这里执行方法
method.Invoke(instance, parameters);
// 方法执行后
foreach (var item in actionList)
{
((ActionFilterAttribute)item).OnActionExecuted();
}
}
catch (Exception ex)
{
// 异常捕捉,包括整个动作
HandleErrorAttribute handleError = (HandleErrorAttribute)filterList.FirstOrDefault(v => v is HandleErrorAttribute);
if (handleError != null)
{
handleError.OnException();
}
}
}
}
}
}
注册
namespace Study.CustomMVCAttribute
{
public class Student
{
[Authorize]
[ActionFilter]
[HandleError]
public void Study()
{
Console.WriteLine($"正在学习");
}
}
}
调用
Student student = new Student();
ControllerActionInvoker.InvokeAction(student, "Study");
手机扫一扫
移动阅读更方便
你可能感兴趣的文章