如何将方法重构为通用基础 class 实现?
How to refactor method into generic base class implementation?
我已经实现了我的存储库 class,但我想知道如何将它的方法重构为一个基础 class,可以通过不同的存储库类型进行扩展。
我从创建下面的基础存储库 class 开始,但不确定每个方法应该有多抽象。另外我应该如何用通用占位符替换模型类型。
在这个example中,抽象方法只包含方法定义而不包含实现:
public abstract Array sort(Array arr);
任何人都可以建议如何重构泛型的方法吗?
我从创建基础抽象存储库 class 开始,但在用通用类型和通用参数替换方法时遇到了困难。
下面的示例是 Delete()
,它特定于 CustomerModel。它应该是通用的,以便更容易地重用 class:
public abstract class BaseRepository
{
public async Task DeleteCustomer(CustomerModel customer)
{
var collection = StartConnection();
var filter = Builders<CustomerModel>.Filter.Where(x => x.Id == customer.Id);
var result = await collection.DeleteOneAsync(filter);
customers.Remove(customer);
}
}
例如,这是完整的 CustomerRepository class,其中包含我的远程数据库的 CRUD 操作。这些方法都是特定于 CustomerModel 的,因此很难重复使用:
public class CustomerRepository : ICustomerRepository
{
private static List<CustomerModel> customers = new List<CustomerModel>();
static CustomerRepository()
{
}
private CustomerRepository()
{
}
public static CustomerRepository Instance
{
get
{
return instance;
}
}
public CustomerModel GetACustomer()
{
if (customers == null)
LoadCustomers();
return customers.FirstOrDefault();
}
public List<CustomerModel> GetCustomers()
{
if (customers.Count == 0)
LoadCustomers();
return customers;
}
public CustomerModel GetCustomerById(ObjectId id)
{
if (customers == null)
LoadCustomers();
return customers.Where(c => c.Id == id).FirstOrDefault();
}
public CustomerModel GetCustomerByEmail(string email)
{
if (customers == null)
LoadCustomers();
return customers.Where(c => c.Email == email).FirstOrDefault();
}
public async Task DeleteCustomer(CustomerModel customer)
{
var collection = StartConnection();
var filter = Builders<CustomerModel>.Filter.Where(x => x.Id == customer.Id);
var result = await collection.DeleteOneAsync(filter);
customers.Remove(customer);
}
public async Task AddCustomer(CustomerModel customer)
{
var collection = StartConnection();
await collection.InsertOneAsync(customer);
customers.Add(customer);
}
public async Task UpdateCustomer(CustomerModel customer)
{
var collection = StartConnection();
var filter = Builders<CustomerModel>.Filter.Where(x => x.Id == customer.Id);
collection.Find(filter).ToString();
var result = await collection.ReplaceOneAsync(filter, customer, new UpdateOptions { IsUpsert = true });
var index = customers.FindIndex(a => a.Id == customer.Id);
customers[index] = customer;
}
private void LoadCustomers()
{
var collection = StartConnection();
try
{
customers = collection.Find(new BsonDocument()).ToListAsync().GetAwaiter().GetResult();
}
catch (MongoException ex)
{
//Log exception here:
MessageBox.Show("A connection error occurred: " + ex.Message, "Connection Exception", MessageBoxButton.OK, MessageBoxImage.Warning);
}
}
private static IMongoCollection<CustomerModel> StartConnection()
{
var client = new MongoClient(connectionString);
var database = client.GetDatabase("orders");
//Get a handle on the customers collection:
var collection = database.GetCollection<CustomerModel>("customers");
return collection;
}
}
不要创建包含实体特定方法的基 class。
从一开始就使基础通用。
public class Repository<T> where T : new()
{
public async Task<T> GetAsync(object key)
{}
public async Task DeleteAsync(T t)
{}
}
添加您喜欢的任何抽象级别。如果您正在使用例如你的仓库中的某种 ORM 这可能就足够了。
您不能更改继承 classes 中的方法名称。如果所有操作方法都相同,那么使用 repos 会更直接。
如果您可以按原样使用 base,则只有 Type
参数发生变化。所以你会实例化例如Repository<Customer>
在你的代码中。
如果实体之间的逻辑不同,则有例如CustomerRepository : Repository<Customer>
并将逻辑放在那里。另外,将 base 标记为 abstract 和 methods abstract/virtual.
我已经实现了我的存储库 class,但我想知道如何将它的方法重构为一个基础 class,可以通过不同的存储库类型进行扩展。
我从创建下面的基础存储库 class 开始,但不确定每个方法应该有多抽象。另外我应该如何用通用占位符替换模型类型。
在这个example中,抽象方法只包含方法定义而不包含实现:
public abstract Array sort(Array arr);
任何人都可以建议如何重构泛型的方法吗?
我从创建基础抽象存储库 class 开始,但在用通用类型和通用参数替换方法时遇到了困难。
下面的示例是 Delete()
,它特定于 CustomerModel。它应该是通用的,以便更容易地重用 class:
public abstract class BaseRepository
{
public async Task DeleteCustomer(CustomerModel customer)
{
var collection = StartConnection();
var filter = Builders<CustomerModel>.Filter.Where(x => x.Id == customer.Id);
var result = await collection.DeleteOneAsync(filter);
customers.Remove(customer);
}
}
例如,这是完整的 CustomerRepository class,其中包含我的远程数据库的 CRUD 操作。这些方法都是特定于 CustomerModel 的,因此很难重复使用:
public class CustomerRepository : ICustomerRepository
{
private static List<CustomerModel> customers = new List<CustomerModel>();
static CustomerRepository()
{
}
private CustomerRepository()
{
}
public static CustomerRepository Instance
{
get
{
return instance;
}
}
public CustomerModel GetACustomer()
{
if (customers == null)
LoadCustomers();
return customers.FirstOrDefault();
}
public List<CustomerModel> GetCustomers()
{
if (customers.Count == 0)
LoadCustomers();
return customers;
}
public CustomerModel GetCustomerById(ObjectId id)
{
if (customers == null)
LoadCustomers();
return customers.Where(c => c.Id == id).FirstOrDefault();
}
public CustomerModel GetCustomerByEmail(string email)
{
if (customers == null)
LoadCustomers();
return customers.Where(c => c.Email == email).FirstOrDefault();
}
public async Task DeleteCustomer(CustomerModel customer)
{
var collection = StartConnection();
var filter = Builders<CustomerModel>.Filter.Where(x => x.Id == customer.Id);
var result = await collection.DeleteOneAsync(filter);
customers.Remove(customer);
}
public async Task AddCustomer(CustomerModel customer)
{
var collection = StartConnection();
await collection.InsertOneAsync(customer);
customers.Add(customer);
}
public async Task UpdateCustomer(CustomerModel customer)
{
var collection = StartConnection();
var filter = Builders<CustomerModel>.Filter.Where(x => x.Id == customer.Id);
collection.Find(filter).ToString();
var result = await collection.ReplaceOneAsync(filter, customer, new UpdateOptions { IsUpsert = true });
var index = customers.FindIndex(a => a.Id == customer.Id);
customers[index] = customer;
}
private void LoadCustomers()
{
var collection = StartConnection();
try
{
customers = collection.Find(new BsonDocument()).ToListAsync().GetAwaiter().GetResult();
}
catch (MongoException ex)
{
//Log exception here:
MessageBox.Show("A connection error occurred: " + ex.Message, "Connection Exception", MessageBoxButton.OK, MessageBoxImage.Warning);
}
}
private static IMongoCollection<CustomerModel> StartConnection()
{
var client = new MongoClient(connectionString);
var database = client.GetDatabase("orders");
//Get a handle on the customers collection:
var collection = database.GetCollection<CustomerModel>("customers");
return collection;
}
}
不要创建包含实体特定方法的基 class。 从一开始就使基础通用。
public class Repository<T> where T : new()
{
public async Task<T> GetAsync(object key)
{}
public async Task DeleteAsync(T t)
{}
}
添加您喜欢的任何抽象级别。如果您正在使用例如你的仓库中的某种 ORM 这可能就足够了。
您不能更改继承 classes 中的方法名称。如果所有操作方法都相同,那么使用 repos 会更直接。
如果您可以按原样使用 base,则只有 Type
参数发生变化。所以你会实例化例如Repository<Customer>
在你的代码中。
如果实体之间的逻辑不同,则有例如CustomerRepository : Repository<Customer>
并将逻辑放在那里。另外,将 base 标记为 abstract 和 methods abstract/virtual.