C# 类的通用工厂?

C# 类的通用工厂?,c#,generics,factory,C#,Generics,Factory,我试图创建一个类,该类使用工厂查找正确的类,然后调用该类上的方法。 但我做错了一些事情,因为VisualStudio中的intellisense不断提醒我错误,当我尝试访问应该在类中的方法时,工厂返回的方法不可用 谁能告诉我我做错了什么 下面是我试图获取类引用的代码: DBBase dal = DALFactory.GetDAL(typeof(T)); myCollection = dal.GetByCriteria(myCriteria, sortExpression

我试图创建一个类,该类使用工厂查找正确的类,然后调用该类上的方法。 但我做错了一些事情,因为VisualStudio中的intellisense不断提醒我错误,当我尝试访问应该在类中的方法时,工厂返回的方法不可用

谁能告诉我我做错了什么

下面是我试图获取类引用的代码:

DBBase dal = DALFactory.GetDAL(typeof(T));

            myCollection = dal.GetByCriteria(myCriteria, sortExpression, startRowIndex, maximumRows, propertyNamesToBypassInstantiation);
以下是DALFactory类的代码:

    internal static class DALFactory
    {
        // GetParser
        internal static DBBase GetDAL(System.Type BOType)
        {
            switch (BOType.Name)
            {
                case "Person":
                    return new PersonDB();
}
            // if we reach this point then we failed to find a matching type. Throw 
            // an exception.
            throw new Exception("Unknown Type");
        }
}
public abstract class DBBase
{
    protected static T GetSingleBO<T>(ref SqlCommand command) where T : BOBase
    {
        return GetSingleBO<T>(ref command, null);
    }


    protected static T GetSingleBO<T>(ref SqlCommand command, List<string> propertyNamesToBypassInstantiation) where T : BOBase
    {
        T BO = default(T);
        try
        {
            command.Connection.Open();
            SqlDataReader reader = command.ExecuteReader();
            if (reader.HasRows)
            {
                reader.Read();
                BOParser parser = BOParserFactory.GetParser(typeof(T));
                parser.PopulateOrdinals(reader);
                if (propertyNamesToBypassInstantiation == null)
                {
                    BO = (T)parser.PopulateBO(reader);
                }
                else
                {
                    BO = (T)parser.PopulateBO(reader, propertyNamesToBypassInstantiation);
                }
                reader.Close();
            }
            else
            {
                // Whever there's no data, we return null.
                BO = default(T);
            }
        }
        catch (Exception ex)
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendFormat("Error populating data: {0}", ex.Message);
            if (ex.InnerException != null)
            {
                sb.AppendFormat("  --  Inner Exception: {0}", ex.InnerException.Message);
            }
            throw new Exception(sb.ToString(), ex);
        }
        finally
        {
            command.Connection.Close();
            command.Connection.Dispose();
        }

        // return the BO, it's either populated with data or null.
        return BO;
    }


    protected static EquatableList<T> GetBOEquatableList<T>(ref SqlCommand command) where T : BOBase
    {
        return GetBOEquatableList<T>(ref command, null);
    }

   protected static EquatableList<T> GetBOEquatableList<T>(ref SqlCommand command, List<string> propertyNamesToBypassInstantiation) where T : BOBase
    {
        EquatableList<T> BOList = new EquatableList<T>();
        try
        {
            command.Connection.Open();
            SqlDataReader reader = command.ExecuteReader();
            if (reader.HasRows)
            {
                // Get a parser for this BO type and populate
                // the ordinals.
                BOParser parser = BOParserFactory.GetParser(typeof(T));
                parser.PopulateOrdinals(reader);

                // Use the parser to build our list of BOs.
                while (reader.Read())
                {
                    T BO = default(T);
                    if (propertyNamesToBypassInstantiation == null)
                    {
                        BO = (T)parser.PopulateBO(reader);
                    }
                    else
                    {
                        BO = (T)parser.PopulateBO(reader, propertyNamesToBypassInstantiation);
                    }
                    BOList.Add(BO);
                }
                reader.Close();
            }
        }
        catch (Exception ex)
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendFormat("Error populating data: {0}", ex.Message);
            if (ex.InnerException != null)
            {
                sb.AppendFormat("  --  Inner Exception: {0}", ex.InnerException.Message);
            }
            throw new Exception(sb.ToString(), ex);
        }
        finally
        {
            command.Connection.Close();
            command.Connection.Dispose();
        }

        return BOList;
    }

    protected static int GetBOCount(ref SqlCommand command)
    {
        int count = 0;

        try
        {
            command.CommandType = CommandType.StoredProcedure;
            DbParameter idParam = command.CreateParameter();
            idParam.DbType = DbType.Int32;
            idParam.Direction = ParameterDirection.InputOutput;
            idParam.ParameterName = "@recordCount";
            idParam.Value = 0;
            command.Parameters.Add(idParam);

            command.Connection.Open();
            command.ExecuteNonQuery();
            command.Connection.Close();
            count = (int)command.Parameters["@recordCount"].Value;
        }
        catch (Exception e)
        {
            throw new Exception("Error populating data", e);
        }
        finally
        {
            command.Connection.Close();
            command.Connection.Dispose();
        }

        return count;
    }

    protected static bool DeleteBO(ref SqlCommand command)
    {
        int result = 0;
        try
        {
            command.Connection.Open();
            result = command.ExecuteNonQuery();
        }
        catch (Exception e)
        {
            throw new Exception("Error deleting data", e);
        }
        finally
        {
            command.Connection.Close();
            command.Connection.Dispose();
        }

        return result > 0;
    }


    protected static int GetFKcount(ref SqlCommand command)
    {
        int count = 0;

        try
        {
            command.CommandType = CommandType.StoredProcedure;
            DbParameter idParam = command.CreateParameter();
            idParam.DbType = DbType.Int32;
            idParam.Direction = ParameterDirection.InputOutput;
            idParam.ParameterName = "@recordCount";
            idParam.Value = 0;
            command.Parameters.Add(idParam);

            command.Connection.Open();
            command.ExecuteNonQuery();
            command.Connection.Close();
            count = (int)command.Parameters["@recordCount"].Value;
        }
        catch (Exception e)
        {
            throw new Exception("Error populating data", e);
        }
        finally
        {
            command.Connection.Close();
            command.Connection.Dispose();
        }

        return count;
    }

    public static T GetById<T>(Guid Id)
        where T : BOBase
    {
        return GetById<T>(Id, null);
    }


    abstract public static T GetById<T>(Guid Id, List<string> propertyNamesToBypassInstantiation)
        where T : BOBase;

    public static EquatableList<T> GetByCriteria<T,TCriteria>(TCriteria myCriteria)
        where T : BOBase
        where TCriteria : BaseCriteria
    {
        return GetByCriteria<T, TCriteria>(myCriteria, null);
    }


    public static EquatableList<T> GetByCriteria<T, TCriteria>(TCriteria myCriteria, List<string> propertyNamesToBypassInstantiation)
        where T : BOBase
        where TCriteria : BaseCriteria
    {
        return GetByCriteria<T, TCriteria>(myCriteria, null, -1, -1, propertyNamesToBypassInstantiation);
    }

    public static EquatableList<T> GetByCriteria<T, TCriteria>(TCriteria myCriteria, string sortExpression, int startRowIndex, int maximumRows)
        where T : BOBase
        where TCriteria : BaseCriteria
    {
        return GetByCriteria<T, TCriteria>(myCriteria, sortExpression, startRowIndex, maximumRows, null);
    }

    abstract public static EquatableList<T> GetByCriteria<T, TCriteria>(TCriteria myCriteria, string sortExpression, int startRowIndex, int maximumRows, List<string> propertyNamesToBypassInstantiation)
        where T : BOBase
        where TCriteria : BaseCriteria;

    abstract public static int GetCountForCriteria<TCriteria>(TCriteria myCriteria)
        where TCriteria : BaseCriteria;

    abstract public static bool Save<T>(T myobject)
        where T : BOBase;


    abstract public static bool Delete<T>(Guid Id)
        where T : BOBase;


    abstract public static int GetFKcount<T>(Guid Id)
        where T : BOBase;

    abstract internal static void CreateCriteriaParameters<T, TCriteria>(ref SqlCommand myCommand, TCriteria myCriteria)
        where T : BOBase
        where TCriteria : BaseCriteria;
}
以下是factory类返回的类基的部分代码:

    internal static class DALFactory
    {
        // GetParser
        internal static DBBase GetDAL(System.Type BOType)
        {
            switch (BOType.Name)
            {
                case "Person":
                    return new PersonDB();
}
            // if we reach this point then we failed to find a matching type. Throw 
            // an exception.
            throw new Exception("Unknown Type");
        }
}
public abstract class DBBase
{
    protected static T GetSingleBO<T>(ref SqlCommand command) where T : BOBase
    {
        return GetSingleBO<T>(ref command, null);
    }


    protected static T GetSingleBO<T>(ref SqlCommand command, List<string> propertyNamesToBypassInstantiation) where T : BOBase
    {
        T BO = default(T);
        try
        {
            command.Connection.Open();
            SqlDataReader reader = command.ExecuteReader();
            if (reader.HasRows)
            {
                reader.Read();
                BOParser parser = BOParserFactory.GetParser(typeof(T));
                parser.PopulateOrdinals(reader);
                if (propertyNamesToBypassInstantiation == null)
                {
                    BO = (T)parser.PopulateBO(reader);
                }
                else
                {
                    BO = (T)parser.PopulateBO(reader, propertyNamesToBypassInstantiation);
                }
                reader.Close();
            }
            else
            {
                // Whever there's no data, we return null.
                BO = default(T);
            }
        }
        catch (Exception ex)
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendFormat("Error populating data: {0}", ex.Message);
            if (ex.InnerException != null)
            {
                sb.AppendFormat("  --  Inner Exception: {0}", ex.InnerException.Message);
            }
            throw new Exception(sb.ToString(), ex);
        }
        finally
        {
            command.Connection.Close();
            command.Connection.Dispose();
        }

        // return the BO, it's either populated with data or null.
        return BO;
    }


    protected static EquatableList<T> GetBOEquatableList<T>(ref SqlCommand command) where T : BOBase
    {
        return GetBOEquatableList<T>(ref command, null);
    }

   protected static EquatableList<T> GetBOEquatableList<T>(ref SqlCommand command, List<string> propertyNamesToBypassInstantiation) where T : BOBase
    {
        EquatableList<T> BOList = new EquatableList<T>();
        try
        {
            command.Connection.Open();
            SqlDataReader reader = command.ExecuteReader();
            if (reader.HasRows)
            {
                // Get a parser for this BO type and populate
                // the ordinals.
                BOParser parser = BOParserFactory.GetParser(typeof(T));
                parser.PopulateOrdinals(reader);

                // Use the parser to build our list of BOs.
                while (reader.Read())
                {
                    T BO = default(T);
                    if (propertyNamesToBypassInstantiation == null)
                    {
                        BO = (T)parser.PopulateBO(reader);
                    }
                    else
                    {
                        BO = (T)parser.PopulateBO(reader, propertyNamesToBypassInstantiation);
                    }
                    BOList.Add(BO);
                }
                reader.Close();
            }
        }
        catch (Exception ex)
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendFormat("Error populating data: {0}", ex.Message);
            if (ex.InnerException != null)
            {
                sb.AppendFormat("  --  Inner Exception: {0}", ex.InnerException.Message);
            }
            throw new Exception(sb.ToString(), ex);
        }
        finally
        {
            command.Connection.Close();
            command.Connection.Dispose();
        }

        return BOList;
    }

    protected static int GetBOCount(ref SqlCommand command)
    {
        int count = 0;

        try
        {
            command.CommandType = CommandType.StoredProcedure;
            DbParameter idParam = command.CreateParameter();
            idParam.DbType = DbType.Int32;
            idParam.Direction = ParameterDirection.InputOutput;
            idParam.ParameterName = "@recordCount";
            idParam.Value = 0;
            command.Parameters.Add(idParam);

            command.Connection.Open();
            command.ExecuteNonQuery();
            command.Connection.Close();
            count = (int)command.Parameters["@recordCount"].Value;
        }
        catch (Exception e)
        {
            throw new Exception("Error populating data", e);
        }
        finally
        {
            command.Connection.Close();
            command.Connection.Dispose();
        }

        return count;
    }

    protected static bool DeleteBO(ref SqlCommand command)
    {
        int result = 0;
        try
        {
            command.Connection.Open();
            result = command.ExecuteNonQuery();
        }
        catch (Exception e)
        {
            throw new Exception("Error deleting data", e);
        }
        finally
        {
            command.Connection.Close();
            command.Connection.Dispose();
        }

        return result > 0;
    }


    protected static int GetFKcount(ref SqlCommand command)
    {
        int count = 0;

        try
        {
            command.CommandType = CommandType.StoredProcedure;
            DbParameter idParam = command.CreateParameter();
            idParam.DbType = DbType.Int32;
            idParam.Direction = ParameterDirection.InputOutput;
            idParam.ParameterName = "@recordCount";
            idParam.Value = 0;
            command.Parameters.Add(idParam);

            command.Connection.Open();
            command.ExecuteNonQuery();
            command.Connection.Close();
            count = (int)command.Parameters["@recordCount"].Value;
        }
        catch (Exception e)
        {
            throw new Exception("Error populating data", e);
        }
        finally
        {
            command.Connection.Close();
            command.Connection.Dispose();
        }

        return count;
    }

    public static T GetById<T>(Guid Id)
        where T : BOBase
    {
        return GetById<T>(Id, null);
    }


    abstract public static T GetById<T>(Guid Id, List<string> propertyNamesToBypassInstantiation)
        where T : BOBase;

    public static EquatableList<T> GetByCriteria<T,TCriteria>(TCriteria myCriteria)
        where T : BOBase
        where TCriteria : BaseCriteria
    {
        return GetByCriteria<T, TCriteria>(myCriteria, null);
    }


    public static EquatableList<T> GetByCriteria<T, TCriteria>(TCriteria myCriteria, List<string> propertyNamesToBypassInstantiation)
        where T : BOBase
        where TCriteria : BaseCriteria
    {
        return GetByCriteria<T, TCriteria>(myCriteria, null, -1, -1, propertyNamesToBypassInstantiation);
    }

    public static EquatableList<T> GetByCriteria<T, TCriteria>(TCriteria myCriteria, string sortExpression, int startRowIndex, int maximumRows)
        where T : BOBase
        where TCriteria : BaseCriteria
    {
        return GetByCriteria<T, TCriteria>(myCriteria, sortExpression, startRowIndex, maximumRows, null);
    }

    abstract public static EquatableList<T> GetByCriteria<T, TCriteria>(TCriteria myCriteria, string sortExpression, int startRowIndex, int maximumRows, List<string> propertyNamesToBypassInstantiation)
        where T : BOBase
        where TCriteria : BaseCriteria;

    abstract public static int GetCountForCriteria<TCriteria>(TCriteria myCriteria)
        where TCriteria : BaseCriteria;

    abstract public static bool Save<T>(T myobject)
        where T : BOBase;


    abstract public static bool Delete<T>(Guid Id)
        where T : BOBase;


    abstract public static int GetFKcount<T>(Guid Id)
        where T : BOBase;

    abstract internal static void CreateCriteriaParameters<T, TCriteria>(ref SqlCommand myCommand, TCriteria myCriteria)
        where T : BOBase
        where TCriteria : BaseCriteria;
}
公共抽象类DBBase
{
受保护的静态T GetSingleBO(ref SqlCommand命令),其中T:BOBase
{
返回GetSingleBO(ref命令,null);
}
受保护的静态T GetSingleBO(ref-SqlCommand命令,List-propertynamestobassinstantiation),其中T:BOBase
{
T BO=默认值(T);
尝试
{
command.Connection.Open();
SqlDataReader=command.ExecuteReader();
if(reader.HasRows)
{
reader.Read();
BOParser parser=BOParserFactory.GetParser(typeof(T));
parser.PopulateOrdinals(读取器);
if(propertyNamesToBypassInstantiation==null)
{
BO=(T)parser.PopulateBO(reader);
}
其他的
{
BO=(T)parser.PopulateBO(读取器,propertyNamesToBypassInstantiation);
}
reader.Close();
}
其他的
{
//如果没有数据,则返回null。
BO=默认值(T);
}
}
捕获(例外情况除外)
{
StringBuilder sb=新的StringBuilder();
sb.AppendFormat(“填充数据时出错:{0}”,例如Message);
if(例如InnerException!=null)
{
sb.AppendFormat(“--内部异常:{0}”,ex.InnerException.Message);
}
抛出新异常(sb.ToString(),ex);
}
最后
{
command.Connection.Close();
command.Connection.Dispose();
}
//返回BO,它要么用数据填充,要么为空。
返回BO;
}
受保护的静态EquatableList GetBOEquatableList(ref-SqlCommand命令),其中T:BOBase
{
返回GetBOEquatableList(ref命令,null);
}
受保护的静态EquatableList GetBOEquatableList(ref SqlCommand命令,List propertyNamesToBypassInstantiation),其中T:BOBase
{
equalTableList BOList=新equalTableList();
尝试
{
command.Connection.Open();
SqlDataReader=command.ExecuteReader();
if(reader.HasRows)
{
//获取此BO类型的解析器并填充
//序数。
BOParser parser=BOParserFactory.GetParser(typeof(T));
parser.PopulateOrdinals(读取器);
//使用解析器构建我们的BO列表。
while(reader.Read())
{
T BO=默认值(T);
if(propertyNamesToBypassInstantiation==null)
{
BO=(T)parser.PopulateBO(reader);
}
其他的
{
BO=(T)parser.PopulateBO(读取器,propertyNamesToBypassInstantiation);
}
添加(BO);
}
reader.Close();
}
}
捕获(例外情况除外)
{
StringBuilder sb=新的StringBuilder();
sb.AppendFormat(“填充数据时出错:{0}”,例如Message);
if(例如InnerException!=null)
{
sb.AppendFormat(“--内部异常:{0}”,ex.InnerException.Message);
}
抛出新异常(sb.ToString(),ex);
}
最后
{
command.Connection.Close();
command.Connection.Dispose();
}
回炉炉;
}
受保护的静态int GetBOCount(ref SqlCommand命令)
{
整数计数=0;
尝试
{
command.CommandType=CommandType.storedProcess;
DbParameter idParam=command.CreateParameter();
idParam.DbType=DbType.Int32;
idParam.Direction=参数Direction.InputOutput;
idParam.ParameterName=“@recordCount”;
idParam.Value=0;
command.Parameters.Add(idParam);
command.Connection.Open();
command.ExecuteNonQuery();
command.Connection.Close();
count=(int)command.Parameters[“@recordCount”].Value;
}
捕获(例外e)
{
抛出新异常(“错误填充数据”,e);
}
最后
{
command.Connection.Close();
command.Connection.Dispose();
}
返回计数;
}
受保护的静态bool DeleteBO(ref SqlCommand命令)
{
int结果=0;
尝试
{
command.Connection.Open();
结果=command.ExecuteNonQuery();
}
捕获(例外e)
{
抛出新异常(“删除数据时出错”,e);
}
最后
{
command.Connection.Close();
command.Connection.Dispose();
}
返回结果>0;
}
受保护的静态int GetFKcount(ref SqlCommand命令)
{
整数计数=0;
尝试
{
command.CommandType=CommandType.storedProcess;
DbParameter idParam=command.CreateParameter();
idParam.DbType=DbType.Int32;
idParam.Direction=参数Direction.InputOutput;
idParam.ParameterName=“@记录
SomeFactory.Instance.Create<IClass1>()...
    static MyFactory()
    {
        // Scan the assembly
        foreach (Type type in Assembly.GetExecutingAssembly().GetTypes())
        {
            MyAttribute[] frameAttributes =
                type.GetCustomAttributes(typeof (MyAttribute), false) as MyAttribute[];
            foreach (MyAttribute myAttribute in frameAttributes)
            {
                objects.Add(myAttribute.SomeKey, type);
            }
        }
    }
public class DALFactory
{
   private Dictionary<Type, Func<DBBase>> factoryMethods;

   public void Register(Type type, Func<DBBase>> producer)
   {
      factoryMethods[type] = producer; //last-in wins
   }

   public DBBase GetObject(Type type)
   {
       if(factoryMethods.ContainsKey(type))
          return factoryMethods[type]();
       return null; //or throw exception
   }

   public Func<DBBase> GetFactoryMethod(Type type)
   {
       if(factoryMethods.ContainsKey(type))
          return factoryMethods[type];
       return null; //or throw exception
   }
}

...

var factory = new DALFactory();
factory.Register(typeof(PersonDB), ()=>new PersonDB());
//Register other named or anonymous factory methods that produce objects
public static bobase GetByCriteria<T,TCriteria>(TCriteria myCriteria)
            where T : bobase
            where TCriteria : BaseCriteria
        {
            T myObject = default(T);
            Type[] myMethodTypes = new Type[]{typeof(string),typeof(int),typeof(TCriteria)};
            System.Reflection.MethodInfo myMethod = myObject.DBclass.GetMethod("GetByCriteria", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static, null, myMethodTypes, null);
            object[] myMethodParameters = new object[]{"someValueHere", 1, myObject};
            return (bobase)myMethod.Invoke(null, myMethodParameters);
        }
public abstract class bobase
    {
        internal virtual Type DBclass
        {
            get
            {
                return Type.GetType(this.GetType().Name + "DB");
            }
        }
    }