简体   繁体   English

抽象工厂实现错误

[英]Abstract Factory implementation error

I want to implement Abstract Factory pattern to maximize code efficiency to read my coımmon reference types. 我想实现抽象工厂模式,以最大程度地提高代码效率,以读取我的命令参考类型。 To achieve this I have the following implementations 为此,我有以下实现

在此处输入图片说明

and to implement the pattern I have implemented the following: 为了实现该模式,我实现了以下内容:

在此处输入图片说明

My code for the RefEntityFactor class is : 我的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;
    }
}

Then I implement a class for spesific type: 然后我为特殊类型实现一个类:

在此处输入图片说明

as

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);
    }

But obviously when I run the code it throws an exception at the line where I mark as comment. 但是很显然,当我运行代码时,它将在我标记为注释的行上引发异常。

How can I correct my implementation? 我该如何纠正实施?

Regards. 问候。

Ultimately, this will be because RefEntity isn't of type T , have you tried taking the approach by constructing the new T , so something like this in your while loop: 最终,这是因为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);

You'll also need to extend your generic constraint to limit your T to require a parameterless constructor as well, so something like: 您还需要扩展泛型约束,以将T限制为也需要无参数构造函数,因此类似:

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

also you should change the SearchPaymentTypes as follows to make it work: 另外,您还应按以下方式更改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();
    }

The problem is the RefEntityFactory creates RefEntity objects. 问题在于RefEntityFactory创建了RefEntity对象。 RefEntitys cannot be cast to IPaymentType because they don't implement IPaymentType. 无法将RefEntity强制转换为IPaymentType,因为它们没有实现IPaymentType。

You don't need to use generic parameters to implement the abstract factory pattern. 您无需使用通用参数即可实现抽象工厂模式。 The abstract factory's method can return IRefEntity: 抽象工厂的方法可以返回IRefEntity:

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

and concrete factories would return the various concrete entity types that implement IRefEntity: 具体工厂将返回实现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;
    }
}

or 要么

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;
    }
}

Or the abstract factory could be an abstract class instead of an interface. 或者抽象工厂可以是抽象类而不是接口。 That would allow common code to be shared by all implementations and avoid duplication of much of eg the SQL queries. 这将允许所有实现共享通用代码,并避免重复许多SQL查询。 But the actual concrete object (eg payroll) creation cannot be shared, each object's construction will need to be unique. 但是实际的具体对象(例如工资)创建不能共享,每个对象的构造都必须是唯一的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM