Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/277.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用存储库模式和工厂方法模式组织我的类/接口?_C#_Design Patterns_Repository Pattern_Factory - Fatal编程技术网

C# 如何使用存储库模式和工厂方法模式组织我的类/接口?

C# 如何使用存储库模式和工厂方法模式组织我的类/接口?,c#,design-patterns,repository-pattern,factory,C#,Design Patterns,Repository Pattern,Factory,我正在创建一个示例应用程序,以了解存储库和工厂方法模式,因为它们将用于更大的项目 我想实现的是能够使网站与不同的ORM工具工作 例如,该网站将实现LINQ到SQL和Ado实体框架类,然后使用工厂方法将使用这些ORM之一“使用配置值”加载存储库对象中的数据 到目前为止,我得到的是如下所示 interface IRepository : IDisposable { IQueryable GetAll(); } interface ICustomer : IRepository { } p

我正在创建一个示例应用程序,以了解存储库和工厂方法模式,因为它们将用于更大的项目

我想实现的是能够使网站与不同的ORM工具工作

例如,该网站将实现LINQ到SQL和Ado实体框架类,然后使用工厂方法将使用这些ORM之一“使用配置值”加载存储库对象中的数据

到目前为止,我得到的是如下所示

interface IRepository : IDisposable
{
  IQueryable GetAll();  
}

interface ICustomer : IRepository
{
}

public class CustomerLINQRepository : ICustomer
{
    public IQueryable GetAll()
    {
       // get all implementation using linqToSql
    }
    public void Dispose()
    {
      throw;
    }
    public IRepository GetObject()
    {
        return this;
    }
}


public class CustomerADORepository : ICustomer
{
    public IQueryable GetAll()
    {
       // get all implementation using ADO
    }
    public void Dispose()
    {
      throw new NotImplementedException();
    }
    public IRepository GetObject()
    {
        return this;
    }
}


// Filling a grid with data in a page
IRepository customers = GetCustomerObject();
this.GridView1.DataSource = customers.GetAll();
this.GridView1.DataBind();
////

public IRepository GetCustomerObject()
{
    return new CustomerLINQRepository(); // this will return object based on a config value later
}

但是我能感觉到有很多设计错误,希望你能帮我找出它,以获得更好的设计。

我不确定
getwant
的命名。你到底想要什么?名称应该更具描述性,可能是
GetCustomerRepository

GetCustomerObject
GetWanted
相同吗


投掷是为了什么?

看起来大部分都不错。我有两点意见:

  • 我不会打电话给您的客户存储库ICustomer。我称之为ICustomerRepository。这更直截了当,并且澄清了接口基于存储库的责任。ICCustomer听起来像是封装客户数据的数据对象
  • 考虑使用IOC容器(google structure map、castle windsor或unity),而不是使用工厂方法。你可能会有很多工厂的方法,这可能会导致混乱。相反,在代码中有一个单独的位置,让IOC连接所有存储库可能会更干净
  • 我的两分钱:

    答:我将添加通用的基本存储库类。无论类型是什么,许多存储库操作都是相同的。它可以节省你大量的打字

    我不明白为什么你的存储库要实现ICustomer接口。 数据对象接口是一种很好的做法,但我认为存储库不应该实现它

    如果您的数据对象有一个通用的实现,我会为它们创建一个基类,并限制存储库只处理该类型的派生类

    我会这样做:

    public interface IEntity
    {
         // Common to all Data Objects
    }
    
    public interface ICustomer : IEntity
    {
         // Specific data for a customer
    }
    
    
    public interface IRepository<T, TID> : IDisposable where T : IEntity
    {
         T Get(TID key);
         IList<T> GetAll();
         void Save (T entity);
         T Update (T entity);
    
         // Common data will be added here
    }
    
    public class Repository<T, TID> : IRepository<T, TID>
    {
         // Implementation of the generic repository
    }
    
    public interface ICustomerRepository
    {
         // Specific operations for the customers repository
    }
    
    public class CustomerRepository : Repository<ICustomer, int>, ICustomerRepository
    {
         // Implementation of the specific customers repository
    }
    
    公共接口的可扩展性
    {
    //对所有数据对象通用
    }
    公共接口ICustomer:IEntity
    {
    //客户的特定数据
    }
    公共接口Iposition:IDisposable,其中T:Entity
    {
    T获取(TID键);
    IList GetAll();
    无效保存(T实体);
    T更新(T实体);
    //公共数据将添加到此处
    }
    公共类存储库:IRepository
    {
    //通用存储库的实现
    }
    公共接口ICCustomerRepository
    {
    //客户存储库的特定操作
    }
    公共类CustomerRepository:存储库,ICCustomerRepository
    {
    //特定客户存储库的实现
    }
    
    用法:

    CustomerRepository repository = new CustomerRepository();
    IList<ICustomer> customers = repository.GetAll();
    // Do whatever you want with the list of customers
    
    CustomerRepository repository=new CustomerRepository();
    IList customers=repository.GetAll();
    //对客户名单做任何你想做的事
    
    这就是我使用NHibernate实现DAL的方式。你可以在“NHibernate in Action”中找到这种用法的一些曲折之处


    我还建议按照Matt的建议使用某种IoC控制器。

    我将其重命名为“GetCustomerObject”,它应该检查配置值,并根据该值返回“CustomerLinqRepository”对象或“CustomerAdorRepository”对象,因此“GetCustomerObject”是工厂方法模式的创建者函数吗?我将其重命名为GetCustomerObject并将抛出更改为“抛出新的NotImplementedException();”好,但请看这行:“IRepository customers=GetCustomerObject();”我正在使用IRepository接口调用客户,这意味着我以后将创建的所有实体都将使用IRepository调用,我希望如果我可以使用ICustomer、ISupplier…调用,这是设计中的错误,或者我的想法是错误的?嗯,当我使用存储库模式时,我创建CustomerRepository对象。CustomerRepository是来自GetCustomerObject函数的内容。很好,你能给我看一下从客户那里获取数据的示例代码吗?我在设计中这样写的:“get collection of customers”,我的设计是这样写的:IRepository customers=GetCustomerObject();this.GridView1.DataSource=customers.GetAll();this.GridView1.DataBind();现在我该怎么写呢?在这两行中:1-公共类存储库:IRepository 2-公共类CustomerRepository:Repository,ICCustomerRepository它给了我这个错误:使用泛型类型“TestApplication1.IRepository”需要“2”类型参数。你能帮我解决吗?@Amr Elgarthy:当然:)那是因为我缺少第二个类型参数(对象的键)。当您将C代码直接写入stack overflow的文本编辑器时,就会发生这种情况:)我再次更新了我的答案。