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
{
/// <summary>
/// 基类不做操作
/// 所有Filter只打印,不实现功能
/// </summary>
public class FilterAttribute : Attribute { }
/// <summary>
/// 权限Filter
/// </summary>
public class AuthorizeAttribute : FilterAttribute
{
public void OnAuthorization()
{
Console.WriteLine("OnAuthorization");
}
}
/// <summary>
/// 动作Filter
/// </summary>
public class ActionFilterAttribute : FilterAttribute
{
public void OnActionExecuting()
{
Console.WriteLine("OnActionExecuting");
}
public void OnActionExecuted()
{
Console.WriteLine("OnActionExecuted");
}
// OnResultExecuting 和 OnResultExecuted 先不管
}
/// <summary>
/// 捕捉异常Filter
/// </summary>
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
{
/// <summary>
/// 实例化
/// </summary>
/// <param name="instance">调用的实例</param>
/// <param name="action">方法名</param>
/// <param name="parameters">参数</param>
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<FilterAttribute>();
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");

仿 MVC 三大特性的更多相关文章

  1. 重温PHP面向对象的三大特性

    PHP面向对象的三大特性:封装性.继承性.多态性. 1. 封装性: 也称为信息隐藏,就是将一个类的使用和实现分开,只保留部分接口和方法与外部联系,或者说只公开了一些供开发人员使用的方法. 于是开发人员 ...

  2. Fis3的前端工程化之路[三大特性篇之声明依赖]

    Fis3版本:v3.4.22 Fis3的三大特性 资源定位:获取任何开发中所使用资源的线上路径 内容嵌入:把一个文件的内容(文本)或者base64编码(图片)嵌入到另一个文件中 依赖声明:在一个文本文 ...

  3. Fis3的前端工程化之路[三大特性篇之资源定位]

    Fis3版本:v3.4.22 Fis3的三大特性 资源定位:获取任何开发中所使用资源的线上路径 内容嵌入:把一个文件的内容(文本)或者base64编码(图片)嵌入到另一个文件中 依赖声明:在一个文本文 ...

  4. Fis3的前端工程化之路[三大特性篇之内容嵌入]

    Fis3版本:v3.4.22 Fis3的三大特性 资源定位:获取任何开发中所使用资源的线上路径 内容嵌入:把一个文件的内容(文本)或者base64编码(图片)嵌入到另一个文件中 依赖声明:在一个文本文 ...

  5. JS三大特性

    抽象 在分析三大特性之前我们要先了解什么叫抽象. 定义: 在定义一个类的时候,实际上就是把一类事物的共有的属性和行为提取出来,形成一个物理模型(模板),这种研究问题的方法就称为抽象 一.封装 定义: ...

  6. Java 浅析三大特性之一继承

    上文Java 浅析三大特性之一封装我们说到Java是一个注重编写类,注重于代码和功能复用的语言.Java实现代码复用的方式有很多,这里介绍一个重要的复用方式--继承. 在介绍继承之前,我们要明确一点, ...

  7. 前端学PHP之面向对象系列第三篇——三大特性

    × 目录 [1]封装 [2]继承[3]多态 前面的话 php面向对象编程的三大特性是封装性.继承性和多态性.本文将介绍php的这三大特性 封装 封装就是把对象中的成员属性和成员方法加上访问修饰符( p ...

  8. 第9章 Java类的三大特性之一:继承

    1.什么是继承 子类继承父类就是对父类的扩展,继承时会自动拥有父类所拥有的处private之外的所有成员作用:增加代码复用语法格式: class 子类名 extends 父类名{…………}第9章 Ja ...

  9. 黑马程序员_ Objective-c 概述及面向对象与三大特性

    -----------android培训.java培训.java学习型技术博客.期待与您交流!------------ (一).语法概述 1. oc介绍:(.m文件) 1> c语言的基础上,增加 ...

  10. 谈谈Java面向对象的三大特性

    Java面向对象的三大特性就是指封装.继承.多态了. 一.封装: 概念:封装是指隐藏对象的属性和实现细节,仅对外提供公共访问方式. (举例:笔记本电脑就是一个封装体,Java语言中最小的封装体就是函数 ...

随机推荐

  1. CyclicBarrier循环屏障源码解析(基于jdk11)

    目录 CyclicBarrier循环屏障源码解析(基于jdk11) 1.1 CyclicBarrier概述 1.2 CyclicBarrier原理 1.2.1 基本结构(jdk11) 1.2.2 aw ...

  2. Python数据类型+运算符

    Python基础数据类型 上期练习讲解 # 练习一.想办法打印出jason l1 = [11, 22, 'kevin', ['tony', 'jerry', [123, 456, 'jason'] ] ...

  3. python基础之hashilb模块、logging模块

    hashlib加密模块 1.何为加密 将文明数据处理成密文数据 让人无法看懂 2.为什么要加密 保证数据的安全,防止密码泄露 3.如何判断数据是否加密 密文数据的表现形式一般都是一串没有规则的字符串( ...

  4. APP异常测试点汇总

    在测试APP时异常测试是非常必要的. 安装卸载中的异常测试 一.安装 安装过程中设备重启 安装过程中息屏 安装过程中断网 安装过程中切换网络 安装过程中收到短信提醒 安装过程中收到来电提醒 安装过程中 ...

  5. django.db.migrations.exceptions.NodeNotFoundError: Migration apitest.0001_initial dependencies reference nonexistent parent node ('product', '0001_initial')

    执行python manage.py makemigrations时出现以下错误 D:\autotestplat>python manage.py makemigrations Tracebac ...

  6. uniapp解析后端返回的html标签

    <rich-text  :nodes="data.content"></rich-text>

  7. 交互式仪表板!Python轻松完成!⛵

    作者:韩信子@ShowMeAI 数据分析实战系列:https://www.showmeai.tech/tutorials/40 本文地址:https://www.showmeai.tech/artic ...

  8. [python] 基于matplotlib实现雷达图的绘制

    雷达图(也称为蜘蛛图或星形图)是一种可视化视图,用于使用一致的比例尺显示三个或更多维度上的多元数据.并非每个人都是雷达图的忠实拥护者,但我认为雷达图能够以视觉上吸引人的方式比较不同类别各个特征的值.本 ...

  9. APIO2022 游记

    Day 0 有人刚登记完房间就把房卡落在房间里了我不说是谁(真不是我,不信去问jth) 下午把gen把模拟赛的题补了一下,T3是个不太可做的虚树上淀粉质dp,先咕着. Day 1 上午来的比较晚,没有 ...

  10. 《深度探索C++对象模型》第四章 Function语意学

    member function相对于nonmember function之间不存在效率之间的差别,因为编译器内部已经将"member 函数实体"转化为对等的"nonmem ...