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

简单工厂和反射

作者: 山猪打不过家猪 | 来源:发表于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

相关文章

  • 简单工厂和反射

    1.简单工厂模式 1.1 提出问题 某个项目需要一个打印报表功能,但是公司有多重报表,有的是excel,有的是wo...

  • 用静态工厂来封装retrofit

    用静态工厂来封装retrofit 利用反射机制和静态工厂模式,对retrofit进行简单的封装 利用反射机制,动态...

  • 设计模式-- 工厂模式

    1 工厂模式的种类 1.1 简单工厂 只有一个工厂,例如通过反射传入Class或者直接通过name字段ifels...

  • 简单工厂

    1.面向接口编程 2.简单工厂模式实例 使用java反射改进:

  • 简单工厂->工厂模式->抽象工厂模式

    说下简单理解: 简单工厂即为静态工厂模式,通过反射机制可以创建对象类。 缺点:不符合开放封闭原则,新加类,需修改工...

  • 相近设计模式比较

    设计模式干货: 简单工厂模式 vs. 工厂模式 vs. 抽象工厂模式简单工厂和工厂模式区别? 简单工厂没有多个子类...

  • iOS开发中工厂模式的体现

    在iOS开发中,简单工厂模式使用得并不多。但是、我认为这是OC反射机制很好的一个例子,简单工厂模式的实质是由一个工...

  • 简单工厂模式+反射动态生产cell

    最近手头里没太多的工作就把之前的代码整了整,梳理了之前的各种工厂模式,算是又学习了一遍。 简单工厂和工厂模式的区别...

  • 设计模式2-工厂模式

    工厂模式分为简单工厂模式、工厂方法模式和抽象工厂模式 简单工厂模式 简单工厂模式,就是建立一个工厂类,对实现了同一...

  • 工厂模式

    工厂模式包含三种模式:简单工厂模式、工厂方法模式和抽象工厂模式。 简单工厂模式 定义简单工厂模式:由一个工厂类根据...

网友评论

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

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