C#反射—解决类的实例化问题

时间:2022-05-15 05:19:12

利用简单工厂模式来改进抽象工厂使用的复杂性(抽象工厂详见 设计模式之—抽象工厂模式

数据表(User)业务处理接口(IUser)

C#反射—解决类的实例化问题C#反射—解决类的实例化问题
namespace FactoryMethodPatternDB.CLASS
{
    interface IUser
    {
        void Insert(User user);
        void GetUser(string id);
    }
}
View Code

数据表(Department)业务处理接口(IDepartment)

C#反射—解决类的实例化问题C#反射—解决类的实例化问题
namespace FactoryMethodPatternDB.CLASS
{
    interface IDepartment
    {
        void Insert(Department dept);
        void GetDept(string id);
    }
}
View Code

SQL操作表(User)类(SqlServerUser)

C#反射—解决类的实例化问题C#反射—解决类的实例化问题
namespace FactoryMethodPatternDB.CLASS
{
    class SqlServerUser:IUser
    {
        public void Insert(User user)
        {
            Console.WriteLine("在User表中插入一条数据{0}!SQL数据库",user);
        }

        public void GetUser(string id)
        {
            Console.WriteLine("通过{0}来查找数据!SQL数据库", id);
        }
    }
}
View Code

SQL操作表(Department)类(SqlServerDepartment)

C#反射—解决类的实例化问题C#反射—解决类的实例化问题
namespace FactoryMethodPatternDB.CLASS
{
    class SqlServerDepartment:IDepartment
    {
        public void Insert(Department dept)
        {
            Console.WriteLine("在{0}表中插入数据!SQL数据库", dept);
        }
        public void GetDept(string id)
        {
            Console.WriteLine("通过{0}查找数据库表!SQL数据库", id);
        }

    }
}
View Code

ACCESS操作表(User)类(AccessUser)

C#反射—解决类的实例化问题C#反射—解决类的实例化问题
namespace FactoryMethodPatternDB.CLASS
{
    class AccessUser:IUser
    {
        public void Insert(User user)
        {
            Console.WriteLine("在{0}表中插入数据!Access数据库",user);
        }
        public void GetUser(string id)
        {
            Console.WriteLine("通过{0}查找数据库表!Access数据库",id);
        }
    }
}
View Code

ACCESS操作表(Department)类(AccessDepartment)

C#反射—解决类的实例化问题C#反射—解决类的实例化问题
namespace FactoryMethodPatternDB.CLASS
{
    class AccessDepartment:IDepartment
    {
        public void Insert(Department dept)
        {
            Console.WriteLine("在{0}表中插入数据!Access数据库", dept);
        }
        public void GetDept(string id)
        {
            Console.WriteLine("通过{0}查找数据库表!Access数据库", id);
        }
    }
}
View Code

工厂接口和工厂类被SelectDB替换:

C#反射—解决类的实例化问题C#反射—解决类的实例化问题
namespace FactoryMethodPatternDB
{
    class SelectDB
    {
        //private static readonly string db = "Sqlserver";
        private static readonly string db = "Access";
        public static IUser CreateUser()
        {
            IUser iuser = null;
            switch (db)
            {
                case "Sqlserver":
                    iuser = new SqlServerUser();
                    break;
                case "Access":
                    iuser = new AccessUser();
                    break;
            }
            return iuser;
        }

        public static IDepartment CreateDept()
        {
            IDepartment idept = null;
            switch (db)
            {
                case "Sqlserver":
                    idept = new SqlServerDepartment();
                    break;
                case "Access":
                    idept = new AccessDepartment();
                    break;
            }
            return idept;
        }
    }
}
View Code

简单工厂模式测试类

C#反射—解决类的实例化问题C#反射—解决类的实例化问题
      //简单工厂与抽象工厂模式相结合
          User user = new User();
            Department dept = new Department();
            IUser iuser = SelectDB.CreateUser();
            iuser.Insert(user);
            iuser.GetUser("ID");
            IDepartment idept = SelectDB.CreateDept();
            idept.Insert(dept);
            idept.GetDept("name");
View Code

  C#反射—解决类的实例化问题

若增加Oracle数据库,则需要更改Switch语句块 违背开放-封闭原则。解决此问题的方法是采用反射

将SelectDB换成反射类(Reflection)

添加反射引用命名空间using System.Reflection;

C#反射—解决类的实例化问题C#反射—解决类的实例化问题
using System.Reflection;
namespace FactoryMethodPatternDB
{
    class Reflection
    {
        private static readonly string AssemblyName = "FactoryMethodPatternDB"; //程序集
        private static readonly string db = "SqlServer";  //业务类的名称为SqlServer + 表名 如(SqlServerUser)方便反射使用

        public static IUser CreateUser()
        {
            string className = AssemblyName + ".CLASS." + db  + "User"; //类名(带命名空间)
            return (IUser)Assembly.Load(AssemblyName).CreateInstance(className);
        }

        public static IDepartment CreateDept()
        {
            string className = AssemblyName + "." + "Department";
            return (IDepartment)Assembly.Load(AssemblyName).CreateInstance(className);
        }
    }
}
View Code

 反射测试类

C#反射—解决类的实例化问题C#反射—解决类的实例化问题
   //反射与抽象工厂模式相结合
          User user = new User();
            Department dept = new Department();
            IUser iuser = Reflection.CreateUser();
            iuser.Insert(user);
            iuser.GetUser("ID");

            IDepartment idept = Reflection.CreateDept();
            idept.Insert(dept);
            idept.GetDept("Name");
View Code

 C#反射—解决类的实例化问题