第十二节:优雅方案(反射动态接口实例化、)

一. 反射实现动态接口实例化

1. 需求

    有三个类 MySqlHelp、OracleHelp、SqlServerHelp,都实现了IDBHelp接口,现在想通过传入一个配置,来决定实例化哪个类。

 

2.  方案1-简单工厂

     通过if判断即可。

/// <summary>
/// 最原始的Factory写法
/// </summary>
public static class DBHelpFactory
{
    public static IDBHelp GetDBHelp(string dbType)
    {
        if (dbType == "sqlserver")
        {
            return SqlServerHelp.GreateDBHelp();
        }
        else if (dbType == "mysql")
        {
            return MySqlHelp.GreateDBHelp();
        }
        else
        {
            return OracleHelp.GreateDBHelp();
        }
    }
}

调用:

    IDBHelp db1 = DBHelpFactory.GetDBHelp("mysql");
    db1.Add();

    IDBHelp db2 = DBHelpFactory.GetDBHelp("sqlserver");
    db2.Add();

 

3. 方案2-反射的应用

(1).  给IDBHelp声明一个Accept方法,表示能否连接这个类型的数据库,所有实现这个接口类都要实现这个方法。

IDBHelp代码

public interface IDBHelp
{
    /// <summary>
    /// 该Help是否可以链接dbType类型的数据库
    /// </summary>
    /// <param name="dbType">数据库类型</param>
    /// <returns></returns>
    public bool Accept(string dbType);
    //下面对应crud方法
    public void Add();
}

MySQLHelp代码(其他类似)

/// <summary>
/// MySQL链接类
/// </summary>
public class MySqlHelp : IDBHelp
{
    public bool Accept(string dbType)
    {
        return dbType.Equals("mysql", StringComparison.InvariantCultureIgnoreCase);
    }
    public void Add()
    {
        Console.WriteLine("mysql添加成功");
    }
    public static IDBHelp GreateDBHelp()
    {
        return new MySqlHelp();
    }
}

(2). 新建一个工厂类 DBHelpFactory2

   A. 声明一个静态List<IDBHelp>字段

   B. 在静态构造函数中,通过反射获取当前程序集中所有实现了IDBHelp接口的类(除去抽象类)

   C. 通过CreateInstance创建对象,添加到dbHelpList中

   D. 在静态方法GetDBHelp中通过遍历+Accept方法的调用,获取指定dbType类型的帮助类

查看代码
 public static class DBHelpFactory2
{
    public static List<IDBHelp> dbHelpList = new();
     static DBHelpFactory2()
    {
        //1. 获取当前程序集中所有实现了IDBHelp接口的类(除去抽象类)
        var allDBHelpTypes = Assembly.GetExecutingAssembly().GetTypes().Where(u => typeof(IDBHelp).IsAssignableFrom(u) && !u.IsAbstract);
        // 获取当前程序集的其他写法:找一个类,然后 typeof(DBHelpFactory2).Assembly
        // 还可以用:this.GetType().Assembly.xxx,但是static不能这么写
        //var allDBHelpTypes = typeof(DBHelpFactory2).Assembly.GetTypes().Where(u => typeof(IDBHelp).IsAssignableFrom(u) && !u.IsAbstract);

        //2. 通过CreateInstance创建对象,添加到dbHelpList中
        foreach (var item in allDBHelpTypes)
        {
            IDBHelp dbHelp =(IDBHelp) Activator.CreateInstance(item)!;
            dbHelpList.Add(dbHelp);
        }
    }
    /// <summary>
    /// 获取指定类型的db帮助类
    /// </summary>
    /// <param name="dbType"></param>
    /// <returns></returns>
    public static IDBHelp GetDBHelp(string dbType)
    {
        foreach (var item in dbHelpList)
        {
            if (item.Accept(dbType))
            {
                return item;
            }
        }
        return null;
    }
}

(3). 调用

    IDBHelp db1=DBHelpFactory2.GetDBHelp("mysql");
    db1.Add();

    IDBHelp db2 = DBHelpFactory2.GetDBHelp("sqlserver");
    db2.Add();

 

 

 

二. 

 

 

 

 

 

 

 

三. 

 

 

 

 

 

 

 

 

!

  • 作       者 : Yaopengfei(姚鹏飞)
  • 博客地址 : http://www.cnblogs.com/yaopengfei/
  • 声     明1 : 如有错误,欢迎讨论,请勿谩骂^_^。
  • 声     明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。
 
posted @ 2022-12-06 17:22  Yaopengfei  阅读(160)  评论(0编辑  收藏  举报