抽象工厂实现错误

时间:2014-12-04 13:26:45

标签: c# design-patterns ado.net

我想实现抽象工厂模式以最大化代码效率来读取我的同步参考类型。为实现这一点,我有以下实现

enter image description here

并实现模式我实现了以下内容:

enter image description here

RefEntityFactor 类的代码是:

public class RefEntityFactory<T> : IRefEntityFactory<T> where T : IRefEntity
{
    public List<T> Search(string sp_name, int? id, string code, int? statusid)
    {
        List<T> irefs = new List<T>();
        string procName = sp_name;
        SqlConnection conn = null;

        using (conn = GetConnection())
        {
            SqlCommand cmd = new SqlCommand(procName, conn);
            cmd.CommandType = CommandType.StoredProcedure;

            if (id.HasValue)
                cmd.Parameters.AddWithValue("@ID", id.Value);
            if (!string.IsNullOrEmpty(code) && !string.IsNullOrWhiteSpace(code))
                cmd.Parameters.AddWithValue("@CODE", code.Trim());
            if (statusid.HasValue)
                cmd.Parameters.AddWithValue("@STATUS", statusid.Value);

            SqlDataReader rd = cmd.ExecuteReader();
            while (rd.Read())
            {
                RefEntity refe = new RefEntity();
                refe.Id = int.Parse(rd["ID"].ToString());
                refe.Code = rd["CODE"].ToString();
                refe.Status = short.Parse(rd["STATUS"].ToString());
                IRefEntity iref = (IRefEntity)refe;

                irefs.Add((T)iref);    // Exception will be THROWN HERE!!!!
            }
            rd.Close();
        }
        return irefs;
    }
}

然后我为spesific类型实现了一个类:

enter image description here

作为

public static List<IPaymentType> SearchPaymentTypes(int? id, string code, int? statusid)
    {
        RefEntityFactory<IPaymentType> fact = new RefEntityFactory<IPaymentType>();

        return fact.Search(@"[dbo].[SEARCH_PAYMENTTYPES]", id, code, statusid);
    }

但很明显,当我运行代码时,它会在我标记为注释的行处抛出异常。

如何更正我的实施?

问候。

2 个答案:

答案 0 :(得分:1)

最终,这是因为RefEntity不属于T类型,您是否尝试通过构建新的T来采用该方法,因此在您的while循环中会出现这样的情况:

T refe = new T();
refe.Id = int.Parse(rd["ID"].ToString());
refe.Code = rd["CODE"].ToString();
refe.Status = short.Parse(rd["STATUS"].ToString());

irefs.Add(ref);

您还需要扩展generic constraint以限制T以要求无参数构造函数,例如:

public class RefEntityFactory<T> : IRefEntityFactory<T> where T : IRefEntity, new()

您也应该按照以下方式更改 SearchPaymentTypes 以使其正常工作:

public static List<IPaymentType> SearchPaymentTypes(int? id, string code, int? statusid)
    {
        RefEntityFactory<PaymentType> fact = new RefEntityFactory<PaymentType>();
        List<PaymentType> list = fact.Search(@"[dbo].[SEARCH_PAYMENTTYPES]", id, code, description, statusid);

        return list.Select(x => (IPaymentType)x).ToList();
    }

答案 1 :(得分:0)

问题是RefEntityFactory创建了RefEntity对象。 RefEntity不能转换为IPaymentType,因为它们不会实现IPaymentType。

您不需要使用通用参数来实现抽象工厂模式。抽象工厂的方法可以返回IRefEntity:

interface IRefEntityFactory
{
    List<IRefEntity> Search(string sp_name, int? id, string code, int? statusid);
}

具体工厂将返回实现IRefEntity的各种具体实体类型:

class PayrollEntityFactory : IRefEntityFactory
{
    public List<IRefEntity> Search(string sp_name, int? id, string code, int? statusid)
    {
        List<IRefEntity> ret = new List<IRefEntity>();
        ret.Add(new PaymentType());
        return ret;
    }
}

class NnnnEntityFactory : IRefEntityFactory
{
    public List<IRefEntity> Search(string sp_name, int? id, string code, int? statusid)
    {
        List<IRefEntity> ret = new List<IRefEntity>();
        ret.Add(new NnnnType());
        return ret;
    }
}

或者抽象工厂可以是抽象类而不是接口。这将允许所有实现共享公共代码,并避免重复大部分例如SQL查询。但是实际的具体对象(例如工资单)创建无法共享,每个对象的构造都需要是唯一的。