How to persist a list of value objects in Domain Driven Design

I'm really interested in to write about domain driven design, but it doesn't come into a simple blog post! real world application in Domain driven design approach are usually big, complex and hard to understand the business. I'm gonna to give an example about the persisting the list of value objects, it's just an implementation example that everybody knows the business.

Suppose that we are going to persist the list of tags with blog post. You know, in DDD  value objects should persist with aggregate root and to doing any kind of operation with value object you should talk to aggregate root.

 Fire up visual studio and create a console application or a class library, and put these below infrastructural classes of DDD in it (you can find the implementation of these class on web, it's not the purpose of this post):

 

  1.  public class EntityBase<T>
  2.     {
  3.         public T Identity { get; set; }
  4.     }
  5.  
  6.  public interface IAggegateRoot
  7.     {
  8.     }
  9.  
  10.   public class ValueObjectBase
  11.     {
  12.     }

 Now , create the aggregateRoot class:

  1.   public class Post : EntityBase<int>, IAggegateRoot
  2.     {
  3.     }
  4.  

as I mentioned, I'm gonna to persist a list of value object(BlogTag). so create the blogTag with this definition: 

  1. public class Tag : ValueObjectBase
  2.     {
  3.         private readonly IList<Tag> _tags;
  4.  
  5.         public Tag(IEnumerable<Tag> tags)
  6.         {
  7.             _tags = new List<Tag>(tags);
  8.         }
  9.  
  10.         public string Name { get; private set; }
  11.  
  12.         public IEnumerable<Tag> Tags
  13.         {
  14.             get { return _tags; }
  15.         }
  16.     }

This class has a property named Name and a constructor which initialize the list of Tags, Now refer to Post class (AggregateRoot) and change implement it like this:

  1.  public class Post : EntityBase<int>, IAggegateRoot
  2.     {
  3.         private readonly IList<Tag> _tags;
  4.         public Post(IEnumerable<Tag> tags, string postTitle, string postBody)
  5.         {
  6.             _tags = new List<Tag>(tags);
  7.             PostTitle = postTitle;
  8.             PostBody = postBody;
  9.         }
  10.         public IEnumerable<Tag> Tags
  11.         {
  12.             get { return _tags; }
  13.         }
  14.  
  15.         public string PostTitle { get; set; }
  16.         public string PostBody { get; set; }
  17.     }

This class is entity and also the root of our aggregate, this constructor will be used in service layer, before starting the service implementation create your repository stuff :

  1. public interface IPostRepository
  2.     {
  3.         void CreatePost(Post post);
  4.     }
  5.  
  6.  public class PostRepository : IPostRepository
  7.     {
  8.         public void CreatePost(Post post)
  9.         {
  10.             //Porsist on Dataabase
  11.         }
  12.     }

now it's time jump on service implementation, first create your PostViewModel Class:

  1.  public class PostViewModel
  2.     {
  3.         public string PostTitle { get; set; }
  4.         public string PostBody { get; set; }
  5.     }

 as I'm interested in to request response pattern so let's create the messages of  CreatingPost:

  1.  public class CreatePostRequest
  2.     {
  3.         public PostViewModel PostViewModel { get; set; }
  4.         public IEnumerable<Tag> Tags { get; set; }
  5.  
  6.         public CreatePostRequest(IEnumerable<Tag> tags)
  7.         {
  8.             Tags = new List<Tag>(tags);
  9.         }
  10.     }

As you saw above when I wanted to create the Tag class I created the constructor with accepting the IEnumerable<T> as I want to send a list of tags to persisting, create the response message: 

  1.  public class CreatePostResponse : Response
  2.     {
  3.     }
  4.     public class Response
  5.     {
  6.         public Status Status { get; set; }
  7.     }
  8.     public enum Status
  9.     {
  10.         Success,
  11.         Fail
  12.     }

Finally it's time to implement the Service class and the goal of this article:

  1.   public interface IPostService
  2.     {
  3.         CreatePostResponse CreatePost(CreatePostRequest request);
  4.     }
  5.  
  6.  public class PostService : IPostService
  7.     {
  8.  
  9.         private readonly IPostRepository _postRepository;
  10.  
  11.         public PostService(IPostRepository postRepository)
  12.         {
  13.             _postRepository = postRepository;
  14.         }
  15.  
  16.         public CreatePostResponse CreatePost(CreatePostRequest request)
  17.         {
  18.             var response = new CreatePostResponse();
  19.             try
  20.             {
  21.                 var tag = new Tag(request.Tags);
  22.                 var post = new Post(tag.Tags, request.PostViewModel.PostTitle, request.PostViewModel.PostBody);
  23.                 _postRepository.CreatePost(post);
  24.             }
  25.             catch (Exception exception)
  26.             {
  27.                 Console.WriteLine(exception.Message);
  28.             }
  29.  
  30.             return response;
  31.         }
  32.     }
  33.  

 

Take a deeper look at the CreatePost method of this Service class, by creating the constructor in Tag and Blog you can pass a list of tags via request and put them in Post class constructor and finally send the object  to repository for persisting.

you can get the source code from here, Cheers!


Tags: DDDesign C#


comments powered by Disqus