加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
C#反射与特性(6)设计一个仿ASP.NET Core依赖注入框架.cs 7.42 KB
一键复制 编辑 原始数据 按行查看 历史
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace Mytest
{
/// <summary>
/// 接口
/// </summary>
public interface ITest
{
string Add(string a, string b);
}
/// <summary>
/// 实现
/// </summary>
public class Test : ITest
{
public string Add(string a, string b)
{
Console.WriteLine("Add方法被执行");
return a + b;
}
}
/// <summary>
/// 需要自动实例化并且进行依赖注入的类
/// </summary>
public class MyClassController
{
private ITest _test;
public MyClassController(ITest test)
{
_test = test;
}
/// <summary>
/// 这是一个 Action
/// </summary>
/// <returns></returns>
public string Action(string a, string b)
{
// 校验http请求的参数
if (string.IsNullOrEmpty(a) || string.IsNullOrEmpty(b))
return "验证不通过";
//开始运行
var result = _test.Add(a, b);
Console.WriteLine("NCC社区", "牛逼");
// 响应结果
return result;
}
}
class Program
{
static void Main(string[] args)
{
while (true)
{
string read = string.Empty;
Console.WriteLine("用户你好,你要访问的控制器(不需要带Controller)");
read = Console.ReadLine();
// 检查是否具有此控制器并且获取 Type
var hasController = IsHasController(read);
// 找不到控制器,报 404 ,让用户重新请求
if (!hasController.Item1)
{
Console.WriteLine("404");
continue;
}
Console.WriteLine("控制器存在,请接着输入要访问的 Action");
read = Console.ReadLine();
// 检查是否具有此 Action 并且获取 Type
bool hasAction = IsHasAction(hasController.Item2, read);
// 找不到,继续报 404
if (hasAction == false)
{
Console.WriteLine("404");
continue;
}
// 目前为止,URL存在,那么就是传递参数了
Console.WriteLine("用户你好,URL 存在,请输入参数");
Console.WriteLine("输入每个参数按一下回车键,结束输入请输入0再按下回车键");
// 开始接收用户输入的参数
List<object> paramList = new List<object>();
while (true)
{
string param = Console.ReadLine();
if (param == "0")
break;
paramList.Add(param);
}
Console.WriteLine("输入结束,正在发送 http 请求 \n");
// 用户的请求已经校验通过并且开始,现在来继续仿 ASP.NET Core 执行
object response = StartASPNETCORE(hasController.Item2, read, paramList.ToArray());
Console.WriteLine("执行结果是:");
Console.WriteLine(response);
Console.ReadKey();
}
}
private static Assembly assembly = Assembly.GetCallingAssembly();
private static Type[] types;
static Program()
{
types = assembly.GetTypes();
}
/// <summary>
/// 判断是否有此控制器,并且返回 Type
/// </summary>
/// <param name="controllerName">控制器名称(不带Controller)</param>
/// <returns></returns>
private static (bool, Type) IsHasController(string controllerName)
{
// 不分大小写
string name = controllerName + "Controller";
if (!types.Any(x => x.Name.ToLower() == name.ToLower()))
return (false, null);
return (true, types.FirstOrDefault(x => x.Name.ToLower() == name.ToLower()));
}
/// <summary>
/// 判断一个控制器中是否具有此方法
/// </summary>
/// <param name="type">控制器类型</param>
/// <param name="actionName">Action名称</param>
/// <returns></returns>
private static bool IsHasAction(Type type, string actionName)
{
// 不分大小写
return type.GetMethods().Any(x => x.Name.ToLower() == actionName.ToLower());
}
/// <summary>
/// 实例化依赖
/// </summary>
/// <param name="type">要被实例化依赖注入的类型</param>
public static object[] CreateType(Type type)
{
// 这里只使用一个构造函数
ConstructorInfo construct = type.GetConstructors().FirstOrDefault();
// 获取类型的构造函数参数
ParameterInfo[] paramList = construct.GetParameters();
// 依赖注入的对象列表
List<object> objectList = new List<object>();
// 为构造函数的每个参数类型,实例化一个类型
foreach (ParameterInfo item in paramList)
{
//获取参数类型:item.ParameterType.Name
// 获取程序中,哪个类型实现了 item 的接口
Type who = types.FirstOrDefault(x => x.GetInterfaces().Any(z => z.Name == item.ParameterType.Name));
// 实例化
object create = Activator.CreateInstance(who, new object[] { });
objectList.Add(create);
}
return objectList.ToArray();
}
/// <summary>
/// 实现依赖注入、调用方法
/// </summary>
/// <param name="type">类型</param>
/// <param name="actionName">方法名称</param>
/// <param name="paramList">调用方法的参数列表</param>
/// <returns></returns>
private static object StartASPNETCORE(Type type, string actionName, params object[] paramList)
{
// 获取 Action 重载方法
// 名字一样,参数个数一致
MethodInfo method = type.GetMethods()
.FirstOrDefault(x => x.Name.ToLower() == actionName.ToLower()
&& x.GetParameters().Length == paramList.Length);
// 参数有问题,找不到合适的 Action 重载进行调用
// 报 405
if (method == null)
return "405";
// 实例化控制器
// 获取依赖对象
object[] inject = CreateType(type);
// 注入依赖,实例化对象
object example = Activator.CreateInstance(type, inject);
// 执行方法并且返回执行结果
object result;
try
{
result = method.Invoke(example, paramList);
return result;
}
catch
{
// 报 500
result = "500";
return result;
}
}
}
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化