美文网首页
简单工厂和反射

简单工厂和反射

作者: 山猪打不过家猪 | 来源:发表于2022-10-06 17:43 被阅读0次

    1.简单工厂模式

    1.1 提出问题

    某个项目需要一个打印报表功能,但是公司有多重报表,有的是excel,有的是word,有些是接口,项目需要设计至少三种报表模块,项目发布只需要修改下配置就可以满足不同用户的需求

    1.2 简单工厂模式解决
    简单工厂原理
    image.png
    分析解决思路

    1)需要一个接口,实现将不同文件处理成为统一打印个格式InterfaceR.cs

    namespace InterfaceDemo
    {
        /// <summary>
        /// 打印接口(产品原型)
        /// </summary>
        public interface IReport
        {
            void StartPrint();
            void EndPrint();
        }
    }
    

    2)有了同意的接口,写处理不同格式的具体类
    ExcelHandler.cs

    namespace InterfaceDemo.Report
    {
        class ExcelHandler : IReport
        {
            public void StartPrint()
            {
                Console.WriteLine("正在处理Excel");
            }
            public void EndPrint()
            {
                Console.WriteLine("结束处理Excel");
            }
        }
    }
    

    WordHandler.cs

    
    namespace InterfaceDemo.Report
    {
        class WordHandler : IReport
        {
            public void StartPrint()
            {
                Console.WriteLine("正在处理Word文档");
            }
            public void EndPrint()
            {
                Console.WriteLine("结束处理Word");
            }
        }
    }
    

    3)具体实现的功能已经完成,需要将实现一个,传入文档名称,自动处理,完成打印功能,所以需要一个工厂可以将这些功能全部集中起来
    Factory.cs

    namespace InterfaceDemo
    {
        class Factory
        {
            public static void runReport(string reportName)
            {
                IReport objReport = null;
                switch (reportName)
                {
                    case "excel": objReport = new ExcelHandler();
                        break;
                    case "word": objReport = new WordHandler();
                        break;
                    case "sql": objReport = new SqlHandler();
                        break;
                }
                objReport.StartPrint();
                objReport.EndPrint();
            }
        }
    }
    

    4)调用,实现自己的功能
    Program.cs

    namespace InterfaceDemo
    {
        class Program
        {
            static void Main(string[] args)
            {
                string reportName = "excel";
                Factory.runReport(reportName);
            }
        }
    }
        
    

    2. 反射

    2.1 反射的概念
    image.png
    2.2 反射的方法
    加载程序集的方式
    • Load() 通过程序集名称加载
    Assembly assembly1 = Assembly.Load("InterfaceDemo");
    
    • LoadFile()LoadFrom()通过绝对路径加载,任何文件的都可以
    //Assembly ass1 = Assembly.LoadFrom(@"E:\CSLeaning\CA1006\InterfaceDemo\bin\Debug\netcoreapp3.1\InterfaceDemo.dll");
    Assembly ass1 = Assembly.LoadFile(@"E:\CSLeaning\CA1006\InterfaceDemo\bin\Debug\netcoreapp3.1\InterfaceDemo.dll");
    

    注意:优先考虑Load() 然后是LoadFrom()

    反射常用方法
    image.png
    • 所有方法都是针对InterfaceDemo里面的ExcelHandler.cs
    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace InterfaceDemo.Report
    {
        class ExcelHandler : IReport
        {
            public void StartPrint()
            {
                Console.WriteLine("正在处理Excel");
            }
            public void EndPrint()
            {
                Console.WriteLine("结束处理Excel");
            }
            public int Add(int n1, int n2)
            {
                return n1 + n2;
            }
        }
    }
    
    
    • 项目结构


      image.png

    1)加载程序集LoadFrom,可以将程序集里面所有的类获取

    Assembly ass1 = Assembly.LoadFrom(@"E:\CSLeaning\CA1006\InterfaceDemo\bin\Debug\netcoreapp3.1\InterfaceDemo.dll");
    Console.WriteLine(ass1);
    
    image.png
    2)获取程序集中定义的所有的类GetTypes()
    Type[] typeList = ass1.GetTypes();
    Console.WriteLine(typeList);
    foreach (var item in typeList)
    {
        Console.WriteLine(item);
    }
    
    image.png
    3)只获取public的类型GetExportedTypes()
    Type[] typeListP = ass1.GetExportedTypes();
    foreach (var item in typeListP)
    {
        Console.WriteLine(item);
    
    }
    Console.WriteLine("***********************");
    
    image.png
    4)获取指定的某个类的TypeGetType()
    //获取指定的某个类的Type
    Type typeExcel = ass1.GetType("InterfaceDemo.Report.ExcelHandler");
    //获取该类的所有方法
    Console.WriteLine(typeExcel.GetMethods());
    foreach (var item in typeExcel.GetMethods())
    {
        Console.WriteLine(item);
    }
    
    image.png

    5)调用ExcelHandler里的无参数,无返回值的方法StartPrint()
    object objExcel = Activator.CreateInstance(); 是实例化ExcelHandler这个类

    //加载程序集
    Assembly ass1 = Assembly.LoadFrom(@"E:\CSLeaning\CA1006\InterfaceDemo\bin\Debug\netcoreapp3.1\InterfaceDemo.dll");
    //获取指定的某个类的Type
    Type typeExcel = ass1.GetType("InterfaceDemo.Report.ExcelHandler");
    MethodInfo method = typeExcel.GetMethod("StartPrint");
    //通过反射创建ExcelHandler的实例对象
    object objExcel = Activator.CreateInstance(typeExcel);
    method.Invoke(objExcel, null);
    
    image.png
    6)调用带参数,带返回值的方法Add()
    Assembly ass1 = Assembly.LoadFrom(@"E:\CSLeaning\CA1006\InterfaceDemo\bin\Debug\netcoreapp3.1\InterfaceDemo.dll");
    //获取指定的某个类的Type
    Type typeExcel = ass1.GetType("InterfaceDemo.Report.ExcelHandler");
    MethodInfo method = typeExcel.GetMethod("Add");
    //通过反射创建ExcelHandler的实例对象
    object objExcel = Activator.CreateInstance(typeExcel);
    object result = method.Invoke(objExcel, new object[] { 102, 203 });
    Console.WriteLine("调用Add方法的返回值结果是:{0}", result);
    

    [图片上传中...(image.png-c6e509-1665371737463-0)]

    using System;
    using System.Reflection;
    
    namespace ReflactDemo
    {
        class Program
        {
            static void Main(string[] args)
            {
                //加载程序集
                Assembly ass1 = Assembly.LoadFrom(@"E:\CSLeaning\CA1006\InterfaceDemo\bin\Debug\netcoreapp3.1\InterfaceDemo.dll");
                //获取所有Type的全名(多个type)
                foreach (var a in ass1.GetTypes())
                {
                    Console.WriteLine( a.FullName);
                }
                Console.WriteLine("***********************");
                //获取指定Type对象(一个type)
                Type typeExcel = ass1.GetType("InterfaceDemo.Report.ExcelHandler");
                //获取ExcelHandler下所有的方法
                MethodInfo[] methods = typeExcel.GetMethods();
                for (int i = 0; i < methods.Length; i++)
                {
                    Console.WriteLine(methods[i].Name);
                }
                Console.WriteLine("***********************");
                //获取指定method——StartPrint
                MethodInfo method = typeExcel.GetMethod("StartPrint");
                Console.WriteLine(method.Name);
                Console.WriteLine("***********************");
                //调用无参数,无返回值的 StartPrint方法
                object objStartPrint = Activator.CreateInstance(typeExcel);
                method.Invoke(objStartPrint, null);
                Console.WriteLine("***********************");
                //找到对应的Add方法
                MethodInfo method2 = typeExcel.GetMethod("Add");
                Console.WriteLine(method2.Name);
                object objAdd = Activator.CreateInstance(typeExcel);
                //调用带参数,带返回值的方法(无重载)
                object result = method2.Invoke(objAdd, new object[] { 102, 203 });
                Console.WriteLine("调用Add方法的返回值结果是:{0}", result);
            }
        }
    }
    
    image.png
    2.3 反射的应用
    image.png

    https://www.cnblogs.com/sxw117886/p/5687590.html

    相关文章

      网友评论

          本文标题:简单工厂和反射

          本文链接:https://www.haomeiwen.com/subject/usubartx.html