Note that there are some explanatory texts on larger screens.

plurals
  1. PODDD in a complex enterprise MVC application, what what is the repository's responsibility and what belongs to the domain?
    primarykey
    data
    text
    <p>I'm working on a complex enterprise application. A big part of it is sharing information and managing data in different ways.</p> <p>I use a Repository pattern for persisting data, but ends up with what I regard as either an Illogical or totally anemic domain.</p> <p>The core of the application is the Users (Employees in this case). I have a concrete example of my problem underneath when implementing a functionality for users to send messages to:</p> <ol> <li>Each other</li> <li>For managers to display a "Must read" message with important information</li> </ol> <p>For the latter I have this (a bit simplified):</p> <pre><code> public class Message { public int Id { get; set; } public DateTime ValidFrom { get; set; } public DateTime ValidTo { get; set; } public string Body { get; set; } public Employee CreatedBy { get; set; } public DateTime CreatedDate { get; set; } public ICollection&lt;Employee&gt; Recipients { get; set; } public void Send(Message message) { //Send the message //This is persisting it in the database and update the table //that maps to the recipients //WHO SENDS IT, THE USER? } } public class User { public int Id { get; set; } public String Name { get; set; } public Department Department { get; set; } public ICollection&lt;Message&gt; Messages { get; set; } public Message Recieve(Message message) { //Mark the message as recieved in DB return message; } public void Read (Message message) { //Mark the message as read in DB } public void Delete (Message message) { //Have to query the database to see if this user can delete //this message //If so, delete the message in DB } //THE USER ALSO THEN //Creates messages //Makes orders //Changes passwords and adress //Checks deliveries //Corrects delivered amounts //Manages an department //Archives documents //Writes new documents //AND A LOT MORE } </code></pre> <p>As you see most of the operations is writing information to the DB, or having to query the DB to get information to make the right decisions. In the enterprise apps I've worked on, most operations are about either managing data, storing settings and user information or logging who did what and when in the database.</p> <p>Most of this fits most natural in the repository. Should I call the repository from the classes above and ask it to save the information? I have a feeling that breaks the rules. Is deleting a message a behavior at all? If not what behavior does a data-centric domain really have?</p> <p>What does the User <em>not</em> do? I have a hard time wrapping my head around that, i.e. a message is basicly data, so it can't do anything in real life. An order can not create itself (it is also just a piece of information), a user must make it and so on. Writing files, exchanging data via xml, services, pdf or whatever is just different ways of sharing and/or persisting the data?</p> <p>I know there must be someway to explain the concept but having spent hours reading about it i have a hard time finding the real meaning of DDD, and the examples I've seen is too far away from a real problem where you have to check history or get info from the DB in some way to make the right decisions. It feels like more of a philosophical exercise than logic... </p> <p>If you can read frustration between the lines, I just want to point out that It's not on anyone other than myself since I can't seem to find out how to implement the message functionality and still do it by the book.</p> <p><strong>Edit</strong></p> <p>Based on question below i see I need to add a bit more information:</p> <p>I use EF Code First so my domain model and persistence model is really the same (as far as I understand) since I havent done any special mapping. A user must retrieve messages at logon to display them, mark it as read, and i he/she wants to, archive it (does not show in list of messages). </p> <p>As my initial question, I have no problem putting all of the needed code in the repositories (get the messages, add a new message, change messsage, mark message as read etc) but that is also my problem, what should then go in the domain model?</p> <p>The application is a MVC web app that is stateless, <strong>does DDD way of thinking belong i a stateless web app in its traditional sense at all?</strong></p> <p>I like the idea behind it though, and was thinking of doing like this.</p> <p>Add a new class to serve the function of an Archive, make the message an aggregate root with the archive as a child:</p> <pre><code> public class MessageArchive { public Message Message { get; set; } public User Recipient { get; set; } public User From { get; set; } private bool Read { get; set; } private bool Archived { get; set; } public void MarkMessageAsRead() { //Do things - i.e. notify sender that the message is read Read = true; } public void ArchiveMessage() { //Do things to archive the message, in this case, mark it as archived Archived = true; } } public class Message { public int Id { get; set; } public DateTime ValidFrom { get; set; } public DateTime ValidTo { get; set; } public string Body { get; set; } public User CreatedBy { get; set; } public DateTime CreatedDate { get; set; } public virtual ICollection&lt;MessageArchive&gt; ArchivedMessages { get; set; } public void Send(IEnumerable&lt;User&gt; recipients, User from) { foreach (var recipient in recipients) { ArchivedMessages.Add(new MessageArchive { From = from, Recipient = recipient, Message = this, }); } } } </code></pre> <p>In create a message and send it would then be:</p> <pre><code> public void Run() { var message = new Message(); var recipients = new List&lt;User&gt;(); //Fill it with recipients message.Send(recipients, currentUser); _unitOfWork.MessageRepository.Add(message); _unitOfWork.Save(); } </code></pre> <p>Am I totally on the wrong track here, should i forget about DDD and just make it work or is this a step towards better design?</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. CODDD is a mindset you can use it in every application. I do web developing and I find it natural to use DDD concepts. I haven't seen the G.Y video yet, but I think (I might be mistaken though) he said at one moment that DDD is just OOP done right. So web aplpciations don't need good OOP? If an application is simply, simply CRUD where you just shove data from a form to the db then you don't need DDD, TDD, DI or anything that could be called a good practice. Simple scripts should be enough, but not all web apps are like that and I think it all depends on the developer/architect.
      singulars
    2. COAbout using DDD for your application, I think that trying to use it will lead you to a model that, later you realize is pretty much the same as the persistence model. It is important when designing the domain model to ignore anything db related. Just try to construct the domain as organic as you can, according to usage needs. If the domain is anemic and you just need to save submitted data, then yeah, you don't need DDD for it. DDD or good practices are not a dogma, the concepts and the mindset matter the most but you have to decide when and what to apply
      singulars
    3. COThanks for the input, he asked it as an open question and It was not 100 % clear if he meant it seriously. I really like the mindset, and the idea behind it makes sense to me, but as you understand I have a hard time implementing it in a sensible way. My application is a lot of CRUD, since the app is about treating ad getting more information in a easy and efficient way. Pretty much everything gets saved to the database in some way, which means pretty much every click on the page either fetches or saves info to the DB. The rest is File IO for the most part, that does not fit in the domain.
      singulars
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload