Давайте сначала разберемся с одним агрегатом: Пост
Теперь, чтобы ответить на ваш вопрос:
Можно ли использовать общую сущность в DDD? Или лучше использовать ValueObject?
Это зависит от того, что вы будете делать с Категория .
Сценарий 1:
У вас есть функция (или страница) в вашем приложении, чтобы показать все сообщения категории. Я хотел бы пойти со следующим дизайном:
public class Category
{
public int Id { get; set; }
//this is my in-memory database. Use repository and service to adjust yours
public static List<Post> Posts;
public Category()
{
Posts = new List<Post>();
}
public void AddPost(Guid id, string title, string body)
{
var post = new Post(id, title, body, this.Id);
//saving the post into in-memory. Perhaps you can check some business logic inside Post entity
Posts.Add(post);
}
// You can retrieve all posts of a single category
public IEnumerable<Post> GetAllPosts()
{
return Posts.Where(x => x.CategoryId == this.Id);
}
}
public class Post
{
public Guid Id { get; private set; }
public string Title { get; private set; }
public string Body { get; private set; }
public int CategoryId { get; private set; }
public Post(Guid id)
{
Id = id;
}
public Post(Guid id, string title, string body, int categoryId)
{
//I prefer to pass guid into domain from external services.
//Using this way, your service will have the id to return to upper layers.
//Alternatively you can create new guid here on your own
Id = id;
Title = title;
Body = body;
CategoryId = categoryId;
}
// you can retrieve a post detail
public Post GetPost()
{
return Category.Posts.FirstOrDefault(x => x.Id == this.Id);
}
}
Я вижу только один агрегированный корень в этом сценарии: Категория .
Сценарий 2:
У вас есть страница сообщений, оттуда пользователи могут просматривать подробные сообщения. Кроме того, у каждого сообщения есть категория, которая будет показана где-то на этой подробной странице. Вы можете иметь следующий простой дизайн:
public class Post
{
public Guid Id { get; private set; }
public string Title { get; private set; }
public string Body { get; private set; }
public string CatKey { get; private set; }
public Post(Guid id)
{
Id = id;
}
public Post(Guid id, string title, string body, string catKey)
{
//I prefer to pass guid into domain from external services.
//Using this way, your service will have the id to return to upper layers.
//Alternatively you can create new guid here on your own
Id = id;
Title = title;
Body = body;
//I don't even bother with category id. This is a simple value object, you can store all of your categories
//into a hashtable of key-value
CatKey = catKey;
}
// you can retrieve a post detail
public Post GetPost()
{
//get your post detail from repo
}
}
Надеюсь, что вы можете принять решение сейчас.