.NET Core中灵活使用反射
2023-12-26 14:45:18
前言
前段时间有朋友问道一个这样的问题,.NET Core中如何通过Attribute的元数据信息来调用标记的对应方法。我第一时间想到的就是通过C#反射获取带有Custom Attribute标记的类,然后通过依赖注入(DI)的方式获取对应服务的方法并通过反射动态执行类的方法,从而实现更灵活的编程方式。
什么是反射?
在 C# 中,反射是指在运行时动态地获取类型的信息并操作对象的能力。使用反射,我们可以在代码中访问程序集、模块、成员等,并且可以操作这些成员的属性、方法、字段和事件等。
反射的作用
-
动态加载程序集。
-
获取类型信息。
-
创建对象和调用方法。
-
访问和操作成员。
-
扩展框架和库。
注意:由于反射是一种非常灵活和强大的机制,但也带来了一定的性能开销。因此,在使用反射时应慎重考虑其适用性,并权衡性能和灵活性的取舍。
自定义一个Attribute类型
///?<summary>
///?自定义一个Attribute类型
///?</summary>
[AttributeUsage(AttributeTargets.Class,?AllowMultiple?=?false)]
public?class?CustomAttribute?:?Attribute
{
????public?string?TargetMethod?{?get;?set;?}
????public?CustomAttribute(string?targetMethod)
????{
????????TargetMethod?=?targetMethod;
????}
}
定义如下两个需要被执行的服务,并使用CustomAttribute标记
///?<summary>
///?前进服务
///?</summary>
[Custom("AdvanceWay")]
public?class?AdvanceService
{
????public?void?AdvanceWay()
????{
????????Console.WriteLine("On?the?move!");
????}
}
///?<summary>
///?后退服务
///?</summary>
[Custom("RetreatWay")]
public?class?RetreatService
{
????public?void?RetreatWay()
????{
????????Console.WriteLine("Be?retreating!");
????}
}
注册需要注入的服务
var?services?=?new?ServiceCollection();
//注册需要注入的服务
services.AddTransient<AdvanceService>();
services.AddTransient<RetreatService>();
反射获取所有带有CustomAttribute特性的类并调用对应方法
static?void?Main(string[]?args)
????{
????????var?services?=?new?ServiceCollection();
????????//注册需要注入的服务
????????services.AddTransient<AdvanceService>();
????????services.AddTransient<RetreatService>();
????????var?provider?=?services.BuildServiceProvider();
????????#region?反射获取所有带有CustomAttribute特性的类并调用对应方法
????????//反射获取所有带有CustomAttribute特性的类
????????var?classes?=?Assembly.GetExecutingAssembly().GetTypes()
????????????.Where(type?=>?type.GetCustomAttributes<CustomAttribute>().Any());
????????foreach?(var?clazz?in?classes)
????????{
????????????//获取标记CustomAttribute的实例
????????????var?attr?=?clazz.GetCustomAttributes<CustomAttribute>().First();
????????????//根据CustomAttribute元数据信息调用对应的方法
????????????var?methodInfo?=?clazz.GetMethod(attr.TargetMethod);
????????????if?(methodInfo?!=?null)
????????????{
????????????????//instance 对象是通过依赖注入容器获取的。这是一种常用的实现方式,可以使用依赖注入解耦程序中各个组件之间的依赖关系,方便测试和维护。
????????????????var?instance?=?provider.GetService(clazz);
????????????????methodInfo.Invoke(instance,?null);
????????????}
????????}
????????#endregion
????????#region?反射获取所有带有CustomAttribute特性的类并调用指定方法
????????var?executionMethod?=?"RetreatWay";
????????foreach?(var?clazz?in?classes)
????????{
????????????//获取标记CustomAttribute的实例
????????????var?attr?=?clazz.GetCustomAttributes<CustomAttribute>().First();
????????????if?(attr.TargetMethod?==?executionMethod)
????????????{
????????????????//根据CustomAttribute元数据信息调用对应的方法
????????????????var?methodInfo?=?clazz.GetMethod(attr.TargetMethod);
????????????????if?(methodInfo?!=?null)
????????????????{
????????????????????//instance 对象是通过依赖注入容器获取的。这是一种常用的实现方式,可以使用依赖注入解耦程序中各个组件之间的依赖关系,方便测试和维护。
????????????????????var?instance?=?provider.GetService(clazz);
????????????????????methodInfo.Invoke(instance,?null);
????????????????}
????????????}
????????}
????????#endregion
????????Console.ReadLine();
????}
输出如下:
文章来源:https://blog.csdn.net/qq_37237487/article/details/135220298
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!