简体   繁体   English

存储库模式中的共享存储库

[英]Shared repositories in repository pattern

Repository dependency? 存储库依赖? Lets say I have a domain that looks like the following: 假设我有一个如下所示的域名:

public class User
{
    public int UserId { get; set; }
    public Lazy<Post> Posts { get; set; }
}

public class Post
{
    public int PostId { get; set; }
    public User Poster { get; set; }
}

A user with my posts. 有我帖子的用户。

How do I set up my repository so that for every user , it returns a list of Post and for every post , I get the Poster ? 如何设置我的存储库,以便为每个user返回一个Post列表,对于每个post ,我都会收到Poster

I have 2 repositories: 我有2个存储库:

public class UserRepository : IUserRepository
{
    public IQueryable<User> GetUsers();
}

public class PostRepository : IPostRepository
{
    public IQueryable<Post> GetPosts();
}

I tried calling from 1 repository to the other, but it ends up in a crash because there is a circular dependency. 我尝试从1个存储库调用另一个存储库,但它最终导致崩溃,因为存在循环依赖关系。

I'm using the POCO method of the repository pattern with entity framework. 我正在使用存储库模式的POCO方法和实体框架。

I have 2 repositories: 我有2个存储库:

 public class UserRepository : IUserRepository { public IQueryable<User> GetUsers(); } public class PostRepository : IPostRepository { public IQueryable<Post> GetPosts(); } 

This is likely to become problematic. 这可能会成为问题。

You likely don't want to simply GetUsers . 您可能不想简单地使用GetUsers As you say, you want child entities loaded with the aggregate, or top-level, entity. 如您所说,您希望子实体加载了聚合或顶级实体。

What will occur is that depending on the context of use - what your immediate purpose is - you will want variations on that User . 会发生什么情况取决于使用环境 - 您的直接目的是什么 - 您将需要该User变体。 You'll likely end up with methods like GetUsers , ' GetUsersWithPosts , GetUsersForImportantReport , GetUsersForAttendingAnIceCreamSocial , etc., etc., ad nauseam. 你最终可能会GetUsersGetUsersGetUsersWithPostsGetUsersForImportantReportGetUsersForAttendingAnIceCreamSocial等等的方法,令人作呕。

What's missing is the concept of a role. 缺少的是角色的概念。

What role are you retrieving the User for? 您检索用户的角色是什么? Model that explicitly here. 这里明确的模型。

Start with a base interface for your aggregate. 从聚合的基本界面开始。 Basic properties can go here 基本属性可以在这里

public interface IUser {
  public Guid UserId { get; set; }
  public string UserName { get; set; }
  public IEnumerable<Posts> { get; set; }
}

Add interfaces to support the roles in which you will use the user. 添加接口以支持您将使用该用户的角色。

public interface IAddPostsToUser : IUser {
  public void AddPost(Post post);
}

And your repository can be defined as such: 您的存储库可以这样定义:

public interface IUserRepository {
  User Get<TRole>(Guid userId) where TRole : IUser;
}

Now, use that role to define a fetching strategy; 现在,使用该角色来定义提取策略;

public interface IFetchingStrategy<TRole> {
  TRole Fetch(Guid id, IRepository<TRole> role)
}

Your repository would get the fetching strategies through injection or service location and call fetch. 您的存储库将通过注入或服务位置和调用获取来获取提取策略。 You can pass the repository in to provide the mechanism for the FetchingStrategy to query or have the FetchingStrategy inject or locate what services it needs to query. 您可以传递存储库以提供FetchingStrategy查询的机制,或让FetchingStrategy注入或查找它需要查询的服务。

Of course, exactly how you query will depend on your ORM. 当然,您的查询方式取决于您的ORM。

But this way of modeling will help avoid many problems with loading entity graphs in different scenarios. 但这种建模方式有助于避免在不同场景中加载实体图形时出现的许多问题。

IMHO, this belongs in the service layer, not the repository layer. 恕我直言,这属于服务层,而不是存储库层。 Repository just wraps the DB. 存储库只包装数据库。

public IQueryable<UserData> GetUsersWithPosts()
{
    return from u in UserRepository.GetUsers()
           select new UserData 
           {
               Id = u.Id,
               Name = u.Name
               Posts = from p in u.Posts
                       select new PostData
                       {
                           Id = u.Id,
                           Title = p.Title
                       }
           };

...add security concerns, aggregation, etc, as needed. ...根据需要添加安全问题,聚合等。

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

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