开发者

Do I must expose the aggregate children as public properties to implement the Persistence ignorance?

开发者 https://www.devze.com 2023-01-26 21:38 出处:网络
I\'m very glad that i found this website recently, I\'ve learned a lot from here. I\'m from China, and my English is not so good. But i will try to express myself what i want to say.

I'm very glad that i found this website recently, I've learned a lot from here.

I'm from China, and my English is not so good. But i will try to express myself what i want to say.

Recently, I've started learning about Domain Driven Design, and I'm very interested about it. And I plan to develop a Forum website using DDD.

After reading lots of threads from here, I understood that persistence ignorance is a good practice.

Currently, I have two questions about what I'm thinking for a long time.

  1. Should the domain object interact with repository to get/save data?
  2. If the domain object doesn't use repository, then how does the Infrastructure layer (like unit of work) know which domain object is new/modified/removed?

For the second question. There's an example code: Suppose i have a user class:

public class User
{
 public Guid Id { get; set; }
 public string UserName { get; set; }
 public string NickName { get; set; }

 /// <summary>
 /// A Roles collection which represents the current user's owned roles.
 /// But here i don't want to use the public property to expose it.
 /// Instead, i use the below methods to implement.
 /// </summary>
 //public IList<Role> Roles { get; set; }

 private List<Role> roles = new List<Role>();
 public IList<Role> GetRoles()
 {
    return roles;
 }
 public void AddRole(Role role)
 {
    roles.Add(开发者_如何学Pythonrole);
 }
 public void RemoveRole(Role role)
 {
    roles.Remove(role);
 }
}

Based on the above User class, suppose i get an user from the IUserRepository, and add an Role for it.

IUserRepository userRepository;
User user = userRepository.Get(Guid.NewGuid());
user.AddRole(new Role() { Name = "Administrator" });

In this case, i don't know how does the repository or unit of work can know that user has a new role?

I think, a real persistence ignorance ORM framework should support POCO, and any changes occurs on the POCO itself, the persistence framework should know automatically. Even if change the object status through the method(AddRole, RemoveRole) like the above example.

I know a lot of ORM can automatically persistent the changes if i use the Roles property, but sometimes i don't like this way because of the performance reason.

Could anyone give me some ideas for this? Thanks.

This is my first question on this site. I hope my English can be understood.

Any answers will be very appreciated.


Should the domain object interact with repository to get/save data?

No, it should not. Reason for that is simple - encapsulation. If we take away everything persistence related from our domain model, we can describe our domain much clearer.

If the domain object doesn't use repository, then how does the Infrastructure layer (like unit of work) know which domain object is new/modified/removed?

Simplest version is - it doesn't. You retrieve and save it back (after operation on aggregate has completed) as a whole:

var user = users.Find(guid);
user.AssignRole(Role.Administrator);
users.Save(user);

I personally rely on NHibernate - it tracks changes itself. If I optimize queries with proper eager/lazy loading, save changes only on http request end, don't forget about transactions, use caching - there is no performance penalty. But for a price - it takes some knowledge to handle that.

One more thing - think twice before using domain driven design for development of forum. This approach fits only for unknown (yet) and complex business domains. It's an overkill for simple applications.

And another thing - stop being ashamed of Your English. It will get better in no time. :)

0

精彩评论

暂无评论...
验证码 换一张
取 消