Question about Repositories and their Save methods for domain objects

后端 未结 2 1529
爱一瞬间的悲伤
爱一瞬间的悲伤 2021-01-31 23:17

I have a somewhat ridiculous question regarding DDD, Repository Patterns and ORM. In this example, I have 3 classes: Address, Company and

2条回答
  •  青春惊慌失措
    2021-01-31 23:40

    I myself have used the IRepository approach lately that Keith suggests. But, you should not be focusing on that pattern here. Instead, there are a few more pieces in the DDD playbook that can be applied here.

    Use Value Objects for your Addresses

    First, there is the concept of Value Objects (VO) you can apply here. In you case, it would be the Address. The difference between a Value Object and an Entity Object is that Entities have an identity; VOs do not. The VO's identity really is the sum of it's properties, not a unique identity. In the book Domain-Drive Design Quickly (it's also a free PDF download), he explains this very well by stating that an address is really just a point on Earth and does not need a separate SocialSecurity-like identity like a person. That point on Earth is the combination of the street, number, city, zip, and country. It can have latitude and longitude values, but still those are even VOs by definition because it's a combination of two points.

    Use Services for combining your entities into a single entity to act upon.

    Also, do not forget about the Services concept in the DDD playbook. In your example, that service would be:

    public class PersonCompanyService
    {
      void SavePersonCompany(IPersonCompany personCompany)
      {
        personRepository.SavePerson();
        // do some work for a new company, etc.
        companyRepository.SaveCompany();
      }
    }
    

    There is a need for a service when you have two entities that need both need a similar action to coordinate a combination of other actions. In your case, saving a Person() and creating a blank Company() at the same time.

    ORMs usualyl require an identity, period.

    Now, how would you go about saving the Address VO in the database? You would use an IAddressRepository obviously. But since most ORMs (i.e. LingToSql) require all objects have an Identity, here's the trick: Mark the identity as internal in your model, so it is not exposed outside of your Model layer. This is Steven Sanderson's own advice.

    public class Address
    {
      // make your identity internal
      [Column(IsPrimaryKey = true
        , IsDbGenerated = true
        , AutoSync = AutoSync.OnInsert)]
      internal int AddressID { get; set; }
    
      // everything else public
      [Column]
      public string StreetNumber { get; set; }
      [Column]
      public string Street { get; set; }
      [Column]
      public string City { get; set; }
      ...
    }
    

提交回复
热议问题