反射、特性综合练习—学习刘老师视频
题目:
1:开发商程序引用开发者dll文件,检索可用的滤波方法,并启动测试;
2:开发商提供带有接口方法的dll文件(SDK)以约束开发者的行为;
3:开发者提供包含滤波方法的dll文件;
一、开发商
新建解决方案,创建工程DllPublishFilter,待用。
添加新 .Net Core Library项目:StdFilter_SDK
删除默认class,添加接口:IFilterStd,定义方法:StandardFilter,如下:
添加特性类UnfinishedAttribute,继承自Attribute
方法体可以留空。
右键点击项目StdFilter_SDK,选择Build:
回到工程DllPublishFilter,添加依赖:StdFilter_SDK
勾选StdFilter_SDK
代码中添加引用 using StdFilter_SDK;
代码及程序结构如下:全部代码见文末
将Build生成的SDK释放给开发商:
在项目生成的代码目录中创建文件夹,名为:Issta_Filter
Issta_Filter用于放置开发商开发的dll插件
二、开发者
新开一个IDE环境:
新建解决方法,命名随意;
新建两个 .Net Core Library项目工程FilterDllCreate 和FilterDllImport,模拟两个开发商各自开发的dll插件,两个工程均引用指定目录中的来自开发商释放的StdFilter_SDK.dll
FilterDllCreate项目
添加Class : FirstOrder.cs 编写代码:
注意添加引用:using StdFilter_SDK;
注意使用接口:public class FirstOrder: IFilterStd
注意实现接口方法:public void StandardFilter(int parameter)
添加Class : KalmanFilter.cs 编写代码:
注意新增特性:[Unfinished]
继续添加class : WeightedAverage.cs,编写代码:
项目结构:
FilterDllImport项目
项目结构:
calss添加四个,代码如下:
编译开发者dll插件
分别右键点击两个项目,选择build,生成dll
从两个工程的代码生成目录中Copy两个dll文件至前述Issta_Filter文件夹内:
三、开发商测试
注意观察:被开发商标注为未开发完特性的滤波算法没有被检索出来;
注意体会:反射的使用
开发商完整程序
using System.Collections.Generic;
using System.IO;
using System.Runtime.Loader;
using System.Linq;
using StdFilter_SDK;
namespace DllPublishFilter
{
class Program
{
static void Main(string[] args)
{
//Console.WriteLine(Environment.CurrentDirectory);
var folder = Path.Combine(Environment.CurrentDirectory, "Issta_Filter");
var files = Directory.GetFiles(folder);
var filterTypes = new List<Type>();
foreach (var file in files)
{
var assembles = AssemblyLoadContext.Default.LoadFromAssemblyPath(file);
var types = assembles.GetTypes();
foreach (var t in types)
{
//if (t.GetMethod("StandardFilter") != null)
if (t.GetInterfaces().Contains(typeof(IFilterStd)))
{
var isUnfinished = t.GetCustomAttributes(false).Any(a => a.GetType() == typeof(UnfinishedAttribute));
if (isUnfinished) continue;
filterTypes.Add(t);
}
}
}
while (true)
{
Console.WriteLine("\nSearching the avaiable methods...");
for (int i = 0; i < filterTypes.Count; i++)
{
Console.WriteLine($"Method {i + 1}: {filterTypes[i].Name}");
}
Console.WriteLine("\n============Let's test the filter==============");
Console.WriteLine("Please choose one method:");
int index = int.Parse(Console.ReadLine());
if ((index > filterTypes.Count) || (index < 1))
{
Console.WriteLine("Error input, no this selection! Retry!");
continue;
}
Console.WriteLine("Please select the parameter:");
Console.WriteLine("Tips: input number from 1 to 10");
int parameter = int.Parse(Console.ReadLine());
var t = filterTypes[index - 1];
var m = t.GetMethod("StandardFilter");
var o = Activator.CreateInstance(t);
m.Invoke(o as IFilterStd, new object[] { parameter });
//var f = o as IFilterStd;
//f.StandardFilter(parameter);
}
}
}
}