gpt4 book ai didi

c# - 在大型项目中使用通用存储库/工作单元模式

转载 作者:行者123 更新时间:2023-11-30 14:55:42 25 4
gpt4 key购买 nike

我正在开发一个相当大的应用程序。该领域有大约 20-30 种类型,实现为 ORM 类(例如 EF Code First 或 XPO,与问题无关)。我已经阅读了几篇关于存储库模式的通用实现并将其与工作单元模式相结合的文章和建议,产生了如下代码:

public interface IRepository<T> {
IQueryable<T> AsQueryable();
IEnumerable<T> GetAll(Expression<Func<T, bool>> filter);
T GetByID(int id);

T Create();
void Save(T);
void Delete(T);
}

public interface IMyUnitOfWork : IDisposable {
void CommitChanges();
void DropChanges();

IRepository<Product> Products { get; }
IRepository<Customer> Customers { get; }
}

这种模式适合真正的大型应用程序吗?每个示例在工作单元中大约有 2 个,最多 3 个存储库。据我了解该模式,在一天结束时,存储库引用的数量(在实现中延迟初始化)等于(或几乎等于)域实体类的数量,因此可以将工作单元用于复杂的业务逻辑实现。例如,让我们像这样扩展上面的代码:

public interface IMyUnitOfWork : IDisposable {
...

IRepository<Customer> Customers { get; }
IRepository<Product> Products { get; }
IRepository<Orders> Orders { get; }

IRepository<ProductCategory> ProductCategories { get; }
IRepository<Tag> Tags { get; }

IRepository<CustomerStatistics> CustomerStatistics { get; }

IRepository<User> Users { get; }
IRepository<UserGroup> UserGroups { get; }
IRepository<Event> Events { get; }

...
}

在想到代码味道之前,可以引用多少存储库?还是这种模式完全正常?我可能会将此接口(interface)分成 2 或 3 个不同的接口(interface),全部实现 IUnitOfWork,但这样使用起来会不太舒服。

更新

我检查了一个基本不错的解决方案 here @qujck 推荐。我对动态存储库注册和“基于字典”的方法的问题是我想享受对我的存储库的直接引用,因为一些存储库会有特殊的行为。因此,当我编写业务代码时,我希望能够像这样使用它,例如:

using (var uow = new MyUnitOfWork()) {
var allowedUsers = uow.Users.GetUsersInRolw("myRole");
// ... or
var clothes = uow.Products.GetInCategories("scarf", "hat", "trousers");
}

所以在这里我受益于我有一个强类型的 IRepository 和 IRepository 引用,因此我可以使用特殊方法(作为扩展方法或通过从基本接口(interface)继承来实现)。如果我使用动态存储库注册和检索方法,我想我会放弃这个,或者至少必须一直做一些丑陋的转换。

对于 DI,我会尝试将一个存储库工厂注入(inject)到我的实际工作单元中,这样它就可以惰性地实例化存储库。

最佳答案

基于我上面的评论和答案 here .

略微修改了工作抽象单元

public interface IMyUnitOfWork
{
void CommitChanges();
void DropChanges();

IRepository<T> Repository<T>();
}

您可以使用扩展方法公开命名存储库和特定存储库方法

public static class MyRepositories
{
public static IRepository<User> Users(this IMyUnitOfWork uow)
{
return uow.Repository<User>();
}

public static IRepository<Product> Products(this IMyUnitOfWork uow)
{
return uow.Repository<Product>();
}

public static IEnumerable<User> GetUsersInRole(
this IRepository<User> users, string role)
{
return users.AsQueryable().Where(x => true).ToList();
}

public static IEnumerable<Product> GetInCategories(
this IRepository<Product> products, params string[] categories)
{
return products.AsQueryable().Where(x => true).ToList();
}
}

根据需要提供数据访问

using(var uow = new MyUnitOfWork())
{
var allowedUsers = uow.Users().GetUsersInRole("myRole");

var result = uow.Products().GetInCategories("scarf", "hat", "trousers");
}

关于c# - 在大型项目中使用通用存储库/工作单元模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24906548/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com