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. python注释、变量、数据类型详细

    目录 1.python注释 2.PEP8规范 3.变量与常量 1.python中的变量 2.变量名的命名规范 3.常量的基本使用 1.python注释 什么是注释? 注释是对代码的解释说明,写注释是为 ...

  2. ConditionAlOnProperties实现可插拔?

    大家好,我是3y,一年CRUD经验用十年的markdown程序员‍常年被誉为职业八股文选手 我又又又又被吐槽了,随之而来,我的消息推送平台开源项目Austin又又又又更新啦,迭代自己的项目多是一件美事 ...

  3. 1+X Web初级笔记查漏补缺+练习题

    学习笔记: position:relative是相对定位,是相对于自身位置移动,但是占据原有空间 absolute是绝对定位,原有空间不保留会被其他元素挤占 绝对定位 absolute不占位置完全浮动 ...

  4. 【好软推荐】Scoop - Windows快速软件安装指南

    在平常生活中如果要安装像git.java.node这些环境的时都需要先去官网下载安装程序,点击安装,之后还需要配置,不仅过程麻烦,而且工具多了之后整理起来也相当不容易,配置也很杂,整个电脑就像被污染了 ...

  5. Potree 002 Desktop开发环境搭建

    1.工程创建 我们使用Visual Studio 2022开发,把下载好后的PotreeDesktop源码添加到Visual Studio中. 打开Visual Studio 2022,新建Asp.N ...

  6. 降本超30%,智聆口语通过 TKE 注册节点实现 IDC GPU 节点降本增效实践

    背景介绍 腾讯云智聆口语评测(Smart Oral Evaluation,SOE)是腾讯云推出的中英文语音评测产品,支持从儿童到成人全年龄覆盖的语音评测,提供单词.句子.段落.自由说等多种评测模式,从 ...

  7. Windowsのcmd命令

    Windowsのcmd命令 网络操作: ipconfig命令: ipconfig -all 查看网络信息 ipconfig -release 释放ip/tcp ipconfig -renew 重新获取 ...

  8. 【Redis 技术探索】「数据迁移实战」手把手教你如何实现在线 + 离线模式进行迁移Redis数据实战指南(离线同步数据)

    离线迁移 与在线迁移相比,离线迁移适宜于源实例与目标实例的网络无法连通的场景,或者源端实例部署在其他云厂商Redis服务中,无法实现在线迁移. 存在的问题 由于生产环境的各种原因,我们需要对现有服务器 ...

  9. MySql树形结构(多级菜单)查询设计方案

    背景 又很久没更新了,很幸运地新冠引发了严重的上呼吸道感染,大家羊过后注意休息和防护 工作中(尤其是传统项目中)经常遇到这种需要,就是树形结构的查询(多级查询),常见的场景有:组织架构(用户部门)查询 ...

  10. P8844 [传智杯 #4 初赛] 小卡与落叶

    简要题意 给出一个 \(n\) 个节点的以 \(1\) 为根的树,每一个节点 \(i\) 带权 \(w_i\),初始时所有节点的权均为 \(0\).有 \(m\) 个操作,支持以下操作: 1 x,对于 ...