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. ATM购物车项目总结

    目录 项目实现思路 ATM项目 优先实现功能 拆分函数 项目路径展示 项目启动文件 start.py 配置文件 setting.py 日志配置字典 日志函数 展示层 src.py 用户注册 获取用户输 ...

  2. 浅谈入行Qt桌面端开发程序员-从毕业到上岗(1):当我们说到桌面端开发时,我们在谈论什么?

    谈谈我自己 大家好,我是轩先生,是一个刚入行的Qt桌面端开发程序员.我的本科是双非一本的数学专业,22年毕业,只是部分课程与计算机之间有所交叉,其实在我毕业的时候并没有想过会成为一名程序员,也没有想过 ...

  3. day06-功能实现05

    家居网购项目实现05 以下皆为部分代码,详见 https://github.com/liyuelian/furniture_mall.git 12.功能11-后台分页(分页显示家居) 12.1需求分析 ...

  4. 洛谷P1434例题分析

    [SHOI2002] 滑雪 题目描述 Michael 喜欢滑雪.这并不奇怪,因为滑雪的确很刺激.可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你.Mic ...

  5. $_GET方法踩坑

    背景 写代码时,遇到一个奇怪的问题:小程序卡券解码接口老是报解码失败,苦寻了一个小时,发现原来是url参数经过thinkphp的I方法被过滤掉,而且涉及到PHP原生的$_GET 原因 I方法底层是原生 ...

  6. 在windows上构建OpenCascade

    基于作者QuaoarsWorkshop的视频Open Cascade Lessons,讲的非常详细,观看需要魔法 什么是OCCT?. 首先,Open CASCADE Technology SDK 是一 ...

  7. 学习ASP.NET Core Blazor编程系列十九——文件上传(下)

    学习ASP.NET Core Blazor编程系列文章之目录 学习ASP.NET Core Blazor编程系列一--综述 学习ASP.NET Core Blazor编程系列二--第一个Blazor应 ...

  8. [python] NetworkX实例

    文章目录 NetworkX实例 1. 基础Basic 2. 绘图Drawing 3. 图标Graph NetworkX实例 代码下载地址 NetworkX 2.4版本的通用示例性示例.本教程介绍了约定 ...

  9. Netty-架构设计及入门程序-3

    一.原生 NIO 存在的问题 1.NIO 的类库和 API 繁杂,使用麻烦:需要熟练掌握 Selector.ServerSocketChannel.SocketChannel.ByteBuffer等. ...

  10. JS按空格和换行或者其他字符进行切割形成数组

    据我所测试,目前最好用的代码是: 方案一 let arr = value.split(/[,,\s\n]/).filter(_ => _) 方案二 let arr = value.replace ...