1、主程序
// See https://aka.ms/new-console-template for more information using BabyStoller.SDK; using System.Runtime.Loader; var folder = Path.Combine(Environment.CurrentDirectory, "Animals"); //在当前项目的文件夹下创建名为【Animals】的子文件夹,得到完整的路径 var files=Directory.GetFiles(folder); //获取路径下的.dll文件 List<Type> animalTypes = new List<Type>(); //用来保存获取到的类型 foreach (var file in files) //遍历.dll文件 { var assembly=AssemblyLoadContext.Default.LoadFromAssemblyPath(file); var types=assembly.GetTypes(); foreach (var t in types) { if (t.GetInterfaces().Contains(typeof(IAnimal))&&!t.GetCustomAttributes(false).Any(a=>a.GetType() == typeof(UnfishedAttribute))) //如果类型实现了IAnimal接口,并且该class不带有【UnfishedAttribute】标记。 //【UnfishedAttribute】标记表示该class尚未完成 { animalTypes.Add(t); //添加到泛型集合中 } } } while (true) //死循环,让程序一直运行下去,保持待机 { for (int i = 0; i < animalTypes.Count; i++) { Console.WriteLine($"{i+1}."+" " + $"{animalTypes[i].Name}"); } Console.WriteLine("==========================="); Console.WriteLine("Please choose an animal."); int index=int.Parse(Console.ReadLine()); if (index>animalTypes.Count||index<1) { Console.WriteLine("no such animal."); continue; } Console.WriteLine("How much Times do you want to listen?"); int times=int.Parse(Console.ReadLine()); var t= animalTypes[index-1]; //t为用户选中的类型object o = Activator.CreateInstance(t); //创建类型对象(实例) var a = o as IAnimal; //里氏替换,实现类引用接口类型的实例 a.Voice(times); //直接调用方法 }
2、项目解决方案
3、接口声明
namespace BabyStoller.SDK { public interface IAnimal { void Voice(int times); } }
4、Attribute标记声明
namespace BabyStoller.SDK { public class UnfishedAttribute:Attribute { } }
5、外部Animal类的声明,每个class都要引用SDK文件
6、对接口的实现
namespace Animals_Dog { public class Chicken:IAnimal { public void Voice(int times) { for (int i = 0; i < times; i++) { Console.WriteLine("你干嘛~哎呦"); } } } }
以外部插件式扩展,来丰富主程序的内容