c# - 是否可以将此代码的第二部分用于存储库模式和泛型

标签 c# .net generics repository-pattern

使用版本 2 是否有任何问题,以获得与版本 1 相同的结果。 或者这只是糟糕的编码。

任何想法

public class Customer
{
    public int CustomerID { get; set; }
    public string EmailAddress { get; set; }
    int Age { get; set; }
}

public interface ICustomer
{
    void AddNewCustomer(Customer Customer);
    void AddNewCustomer(string EmailAddress, int Age);
    void RemoveCustomer(Customer Customer);
}

public class BALCustomer
{
    private readonly ICustomer dalCustomer;
    public BALCustomer(ICustomer dalCustomer)
    {
        this.dalCustomer = dalCustomer;
    }

    public void Add_A_New_Customer(Customer Customer)
    {
        dalCustomer.AddNewCustomer(Customer);
    }

    public void Remove_A_Existing_Customer(Customer Customer)
    {
        dalCustomer.RemoveCustomer(Customer);
    }

}

public class CustomerDataAccess : ICustomer
{

    public void AddNewCustomer(Customer Customer)
    {
        // MAKE DB CONNECTION AND EXECUTE
        throw new NotImplementedException();
    }

    public void AddNewCustomer(string EmailAddress, int Age)
    {
        // MAKE DB CONNECTION AND EXECUTE
        throw new NotImplementedException();
    }

    public void RemoveCustomer(Customer Customer)
    {
        // MAKE DB CONNECTION AND EXECUTE
        throw new NotImplementedException();
    }


}

//          VERSION 2 

public class Customer_New : DataRespository<CustomerDataAccess>
{
    public int CustomerID { get; set; }
    public string EmailAddress { get; set; }
    public int Age { get; set; }
}

public class DataRespository<T> 
    where T:class,new()
{

    private T item = new T();
    public T Execute { get { return item; } set { item = value; } }
    public void Update()
    {
        //TO BE CODED
    }

    public void Save()
    {
        //TO BE CODED
    }

    public void Remove()
    {
        //TO BE CODED
    }
}    

class Program
{
    static void Main(string[] args)
    {
        Customer_New cus = new Customer_New()
        {
            Age = 10,
            EmailAddress = "this@demo.com"
        };

        cus.Save();
        cus.Execute.RemoveCustomer(new Customer());

        // Repository Version

        Customer customer = new Customer()
        {
            EmailAddress = "new@demo.com",
            CustomerID = 10
        };

        BALCustomer bal = new BALCustomer(new CustomerDataAccess());
        bal.Add_A_New_Customer(customer);
    }
}

最佳答案

你有很多事情没有意义。

首先,属性的名称应始终是名词(单数或复数)或“存在”动词,如 Is* 或 Has*。这些是对象的属性,应该类似于您在回答“请描述一下您的办公 table 好吗?”这样的问题时所说的内容。 Execute 是一个操作,因此应该是一个方法。同样,您在版本 1 中的命名约定应该是 PascalCased,这意味着没有下划线并且所有单词的首字母都应该大写。这些不是顽固的真理,但它们被认为是OOP 常见的 C# 编码标准。

其次,您的 main 方法中的代码实际上并未在您的泛型类中实现任何内容。您的类实际做的唯一一件事是创建 CustomerDataAccess 的实例。 Save() 方法不会执行任何操作,除非您特别能够调用 item.Save() 以便在您的应用程序上使用您的保存、更新、删除功能泛型类,您的 CustomerDataAccess 类将必须实现您的泛型类所期望的接口(interface)。例如:

public interface IDataAccess<T> : where T : YourBaseObject {
   public void Update(T item);
   public void Save(T item);
   public void Remove(T item);
}

public class Customer : YourBaseObject {
    public int CustomerID { get; set; }
    public string EmailAddress { get; set; }
    public int Age { get; set; }
}

public class CustomerDataAccess : 
    DataRespository<IDataAccess<Customer>> {
    public void PerformCustomerOnlyAction(Customer customer) { 
     /* do stuff */
    }
}

现在,您可以创建一个通用类来处理基本的 CRUD 功能,所有其他功能都可以通过 BaseRepository 属性访问。

/* e.g. T = IDataAccess<Customer>, K = Customer */
public class DataRespository<T>
   where T : IDataAccess<K>, new()
   where K : YourBaseObject, new()
{

    private T _base;
    public T BaseRepository { 
          get { 
             if(_base == null)
                 _base = Activator.CreateInstance<T>(); 
             return _base;
          } 
    }
    public void Update(K item) { /* functionality for YourBaseObject */ }
    public void Save(K item) { /* functionality for YourBaseObject */ }
    public void Remove(K item) {  /* functionality for YourBaseObject */ }
}   

class Program
{
    static void Main(string[] args)
    {
        var repository = new CustomerDataAccess();
        Customer c = new Customer {
            Age = 10,
            EmailAddress = "this@demo.com"
        };
        repository.Save(c);
        // This pass-through is no longer needed, but shown as example
        // repository.BaseRepository.PerformCustomerOnlyAction(c);
        repository.PerformCustomerOnlyAction(c);
    }
}

注意 我是从头/内存中完成上述代码的。通用类型约束可能无法完全按照我的要求工作。

ASP.NET 3.5 Unleashed由 Stephen Walther 撰写,有几章是关于创建存储库模式的,其设置类似于您在版本 2 中尝试完成的内容。他还在业务逻辑层和数据访问层之间拆分处理。尽管这本书很大(将近 2000 页)并且许多代码示例是多余的或最好作为 CD 的一部分,但他对初学者到中级范围的内容进行了相当深入的介绍。它在亚马逊上的售价约为 25 美元。

关于c# - 是否可以将此代码的第二部分用于存储库模式和泛型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2838039/

相关文章:

c# - ShowDialog 退出时如何防止焦点改变?

c# - .net中度数转弧度的扩展方法

generics - 没有类型参数的泛型类型上的泛型结构

generics - 具有标记特征的Rust meta/复合结构

c# - WinRT 记录到文件

c# - 如何在 Android Image Gallery 中保存从 unity 拍摄的照片?

c# - 反序列化 iso 8601 日期

asp.net - 如何使用另一个表中的列来引用两个表 - Entity Framework

c# - exe 需要 .NET 桌面运行时

java - java.util.Arrays.copyOf(U[], int, Class<? extends T[]>) 中通用通配符的优点