Designing DTO's and DO service layer - domain-driven-design

I'm designing a new large scale application which needs to be as flexible as possible.
I chose designing mainly with DDD..
My question is about transferring DTO object's back to DO objects in my service layer.
i.e:
This is my domain object mapped to the DB (using ORM)
public class Cat
{
int ID {get; set;}
string Name {get; set;}
string BloodType {get; set;}
string Color {get; set;}
void Run(){...}
void Purr() {...}
}
Methods and some properties are only needed for server actions.
That's why I designed another, data transfer object for this cat type:
public class CatDTO
{
int ID {get; set;}
string Name {get; set;}
}
In the middle, I'll set up an object mapper to translate my DO's to DTO's (and vice versa).
When a client would like to update a cat's name he will call a service like this
public void UpdateCat(CatDTO cat)
{
// What will happen here?
Cat serverCat = Mapper.GetCat(CatDTO);
CatDao.SaveOrUpdate(serverCat);
}
When the mapper is translating the DTO object back to DO it will have to hit the DB in order to fill the missing properties of the Cat object (blood type, etc')
Needles to say this action is absurd but without filling the empty properties the rest of the server side cannot work with the Cat object because it relies on those missing properties (even if i just try to update the data in the DB, My ORM will update the bloodtype field as an empty string!)
I searched for this problem and couldn't find any explenation on the web (or at least someone who is bothered with the issue as I do)
Am I designing it the wrong way? Maybe I missed something in my DDD?
Thanks, Pavel.

The usual workflow for this use case is: retrieve mapped domain object by ID, apply updates specified by the DTO, commit unit of work. What you refer to as the DAO is normally called a repository in DDD. The code should look more like:
public void UpdateCat(CatDTO catDto)
{
Cat cat = this.catRepository.Get(cat.ID);
cat.Name = catDto.Name;
this.catRepository.Commit();
}
The Commit step can come in a variety of ways. It can either be an explicit save, or the unit of work can be committed outside of the UpdateCat method. This workflow applies to all related scenarios as well. Generally, domain behavior involves retrieving the appropriate entity, invoking some behavior on that entity and then committing the resulting changes to the database.
Also, DTOs shouldn't directly map back into existing entities. Instead, it is better to think of them as representing changes to be applied to existing entities and the code should reflect this. This is in part because an existing entity is "owned" by the repository and the repository is responsible for reconstitution, not a DTO mapper.

Related

How to manage separation of concerns when using ServiceStack AutoQuery

I am having some issues with how to organise my AutoQuery code. My project structure currently looks like:
/Project
/Project.ServiceInterface
Service.cs
/Project.Logic
Manager.cs
/Types
DbModel.cs
/Project.ServiceModel
Request.cs
/Types
DtoModel.cs
With this setup, the ServiceModel has no knowledge of the Logic models. Because of this, I can't make a request query like QueryDb<DbModel, DtoModel> without essentially duplicating all my DbModel objects in my ServiceModel or adding a dependency to Logic in ServiceModel. I also have custom AutoQuery service implementations and inside those I want to be able to leverage code that has been written using my DbModels elsewhere.
Does anyone have any recommendations or relevant examples? I feel like I'm approaching this problem incorrectly and making it more complex than need be. Thanks.
Auto Query lets you create Services by defining a Request DTO as such all Types it references must also be the ServiceModel Assembly, so you'd either need to move the Data Models your AutoQuery Services references to your ServiceModel project or annotate your DTO so that it can be used by OrmLite to query your RDBMS Table where it can use the [Alias] attribute where names differ and the [Ignore*] attributes depending on whether the property should exist in OrmLite or Serialization, e.g:
[Alias("MyTable")]
public class MyDto
{
[Alias("DbName")]
public string DtoName { get; set; }
[Ignore]
public string IgnoredInOrmLite { get; set; }
[IgnoreDataMember]
public string IgnoredInSerialization { get; set; }
}
Otherwise you're not going to be able to use Auto Query and would need to create Custom Services whose internal implementation makes use of your Data Models where they're hidden from your public Services Contract.
Personally I'd recommend moving the Data Models you need to your ServiceModel Assembly (that continues to use the same Namespace as your other DataModels) as OrmLite DataModels are POCOs that like DTOs typically don't need any additional references other than the impl-free ServiceStack.Interfaces.

What format is data in when passed to a domain layer for validations

I am confused about what form data is supposed to be in when passing data from a User Interface in the Presentation Layer to an Application Layer then the Domain Layer for validations. I am passing in a DTO but I've heard I should not. Rather that I should only pass in primitives and scalars to the Domain Layer. I'm not sure how this is done if not using a DTO class structure. Below is how I am using a DTO from my UI:
My User Interface may have values as follows on screen:
Product Name: Product ABC
Product Code: 1234
Description: a description
When the user clicks the submit button to add this record to the database I build a DTO as follows:
public class NewProductDto
{
public string ProductName {get;set;}
public string ProductCode {get;set;}
public string Description {get;set;}
}
I pass this DTO to the Application Layer then to the Domain Layer where it reads the values to validate and create a new instance of an entity.
If I am not supposed to be doing this then how are the values from the UI supposed to be packaged for the Application Layer to receive and send to the Domain Layer to perform validations and creation of new entities?
Maybe just a simple data structure?
struct NewProduct
{
public string ProductName;
public string ProductCode;
public string Description;
}
struct NewProduct aNewProductStructure;
(i.e. CreateNewProduct(aNewProductStructure) instead of CreateNewProduct(aNewProductDto) ?
Thanks in advance.
---------- Update 2/24/2016 9:58 am
Okay based on recent information I overlooked it appears the Application Layer is supposed to receive the DTO from the UI but then converts it into pieces to pass to the domain. So in my example above the Application Layer should pass the new product to be created as follows to the domain layer:
CreateNewProduct(ProductName, ProductCode, Description);
Definition for CreateNewProduct:
public int CreateNewProduct(string ProductName, string ProductCode, string Description)
{
....
}
Basically, I am supposed to pass in the individual values to the Domain.
Using a DTO to transmit data across a process boundary is a Good Thing.
The anti-corruption component, which is responsible for ensuring that the messages to the domain are well formed, itself lives in the application component.
Which is to say, it is normal for the application component to take the DTO, and create from it value types that will be recognized by the domain. All of the data validation (range checking on value types, decoding of strings, null checks, etc) happens in the application layer.
So this is close:
public int CreateNewProduct(string ProductName, string ProductCode, string Description)
{
....
}
But even better would be
public int CreateNewProduct(ProductName productName, ProductCode productCode, Description description)
{
....
}
With all of the data validation done by the application layer, the domain is left to reconcile the command with the business rules -- given the current state of the domain, is creating a new product with these arguments allowed?
The domain model describes any changes to the application using the types that it understands, and the application is then responsible for normalizing the result (ie, building a DTO to send back to the client, passing changes to the persistence component, etc).

Domain driven design - How to check uniqueness of one property in domain object

I'm developing an application using domain driven design. One of the patterns I've been using is Repository pattern. For the sake of simplicity, let's say I have following classes and interfaces.
Car - domain class representing car domain concept.
public class Car {
public int Id {get;private set;}
public string SomeUniqueCode {get;private set;}
}
ICarRepository - interface for adding, deleting or saving changes to Car objects.
public interface ICarRepository{
Car AddCar(Car c);
void DeleteCar(Car c);
}
My problem is, how to check uniqueness of SomeUniqueCode property among all Car objects in the database? That property is changed by user (not auto-generated) at any time during the object life-cycle. Of course, one solution would be to put the unique key in the database, but that is not the principle of DDD. I've seen Specification pattern used to validate single objects. How would that pattern be applied to a set of Car objects?
Is it legitimate that Specification class (let's call it CheckUniqueCarSpecification) accesses ICarRepository?
A repository mimics an in-memory collection. What I have used before is a Contains method as opposed to a Find method, I guess you could have either. A query layer could also be used for this. Just as you have a CarRepository you could have a CarQuery. Trying to check for uniqueness in the domain is somewhat pesky. I would do a check for the sake of convenience but still rely on the DB to raise the exception since you should also handle that case. Using the specification pattern for this may be more effort than it is worth.
Since repository is a 'collection' I wouldn't have Commit and Rollback on there.
Use DomainService ICarCodesLibrary.
public class Car {
ctor(string someUniqueCode, ICarCodesLibrary codes)
{
// the check
codes.IsValidCode(someUniqueCode)
}
public int Id {get;private set;}
public string SomeUniqueCode {get;private set;}
}
Implement the interface in the place where u create the Car object and inject it. Also get rid of the properties and use fields. The ID is OK to be a prop.

Should I add item using repository pattern or a create event if I am using domain events?

I am trying to understand the Domain Event pattern illustrated by Udi Dahan with regard to adding new domain entities in a certain situation.
Now normally with entities I would create them and then add them via repository. I assume I would still do this?
My example is we normally add assets to the system. Like this:
var asset= new Asset();
/*bunch of prop setting*/
_assetRepository.Add(asset);
However asset creation is an event that we want to follow certain processes as a result of. Therefore it was suggested by developer we no longer need to do this as it could be handled by domain event:
var asset= new Asset();
/*bunch of prop setting*/
asset.Create(location);
Now a create method would raise an event and be handled by a create event handler that basically just inserts it into the repo and does some other stuff email the warehouse manager of the create location etc.
However having a create event on the asset looks pretty active record to me. However in the domain people talk about new assets being created. So we were not sure.
Thoughts?
The created domain event should be raised in the constructor of the Asset class because that is when that particular entity is created. In your current implementation, this would be erroneous because the Asset entity provides a parameterless constructor. Instead, create a constructor which has all required properties as parameters thereby preventing creation of an Asset entity in an inconsistent state. It could look like this:
public class Asset
{
public Asset(string prop1, decimal prop2)
{
this.Prop1 = prop1;
this.Prop2 = prop2;
DomainEvents.Raise(new AssetCreated(prop1, prop2));
}
public string Id { get; private set; }
public string Prop1 { get; private set; }
public decimal Prop2 { get; private set; }
}
You still have to persist the entity using the repository after creating it. This can be problematic because the handlers for the AssetCreated cannot reference its ID since it is not yet assigned when they are notified. If using event sourcing, then the creation event would be explicitly stored in the underlying event store.
I've been struggling for this problem for quite a long time. But no good solution. I think,
A domain event shouldn't be published or handled before the aggregate it belongs to being successfully persisted
It's not the application layer's responsibility to publish any domain events
So far, I think the best approach is to take advantage of AOP. We can "fire" events in the aggregate, but instead of dispatching them instantly, we keep it in a queue, and really dispatch it after the corresponding transaction successes. We can define a custom #Transactional interceptor to achieve this, thus keeping the app service from knowning any concept of "event publishing".

Domain Driven Development: Detecting changes (.NET)

I've just started with Domain Driven Design and trying to apply it for my current project.
I've started with a pure domain model and now stuck with my Data Access layer. I have a completely home made data access layer therefore no any of well known ORM tools can be applied here.
I cannot figure out how to deal with updates. Let's say I have the following Objects:
public class Document : Entity
{
public IPropertiesCollection Properties { get; set; }
public IContents Contents { get; set; }
}
public class PostalDocumentsPackage : Entity
{
public String Name { get; set; }
public DateTime DeliverDate { get; set; }
public ICollection<Document> Documents { get; set; }
}
I have corresponding repositories IDocumentsRepository and IPostalDocumentPackagesRepository for retrieving objects (for now).
The problem I deal with now is to situation when i want to add a new document do Documents collection of PostalDocumentsPackage. Basically I see two possible cases here:
1) Implement the collection that track changes in original collection and holds lists of items that were updated\removed.
2) Implement separate methods in repository for adding documents to the package.
I wonder are these approaches is ok or can cause problems in future? or there is another alternatives?
Typically change tracking would be handled by an ORM such as NHibernate. In your case you may be able to do the following:
Select new documents based on the value of the identity property.
Issue a SQL delete statement before re-inserting into the table.
A problem with either approach is that the documents collection may be big, such that loading all documents for each PostalDocumentsPackage may be a bottleneck. Also you must consider whether you need change tracking on the Document entity in addition to the documents collection. If so, then you would need to implement change tracking for the Document class as well. Given that you're not using an ORM I would suggest solution #2 since solution #1 will lead you down a path of re-implementing change tracking, which among other things would pollute your domain classes. You may also consider a CQRS/Event Sourcing architecture in which change tracking is made explicit.

Resources