32

I've started learning about DDD and wanted to know how others have organised their projects.

I've started off by organising around my AggregateRoots:

MyApp.Domain (namespace for domain model)

MyApp.Domain.Product
- Product
- IProductService
- IProductRepository
- etc

MyApp.Domain.Comment
- Comment
- ICommentService
- ICommentRepository
- etc

MyApp.Infrastructure
- ...

MyApp.Repositories
- ProductRepository : IProductRepository
- etc

The problem i've bumped into with this is that i have to reference my domain product as MyApp.Domain.Product.Product or Product.Product. I also get a conflict with my linq data model for product....I have to use ugly lines of code to distiguish between the two such as MyApp.Domain.Product.Product and MyApp.Respoitories.Product.

I am really interested to see how others have organised their solutions for DDD...

I am using Visual Studio as my IDE.

Thanks alot.

Nietzche-jou
  • 13,657
  • 4
  • 32
  • 45

5 Answers5

23

I try to keep things very simple whenever I can, so usually something like this works for me:

Myapp.Domain - All domain specific classes share this namespace

Myapp.Data - Thin layer that abstracts the database from the domain.

Myapp.Application - All "support code", logging, shared utility code, service consumers etc

Myapp.Web - The web UI

So classes will be for example:

  • Myapp.Domain.Sales.Order
  • Myapp.Domain.Sales.Customer
  • Myapp.Domain.Pricelist
  • Myapp.Data.OrderManager
  • Myapp.Data.CustomerManager
  • Myapp.Application.Utils
  • Myapp.Application.CacheTools

Etc.

The idea I try to keep in mind as I go along is that the "domain" namespace is what captures the actual logic of the application. So what goes there is what you can talk to the "domain experts" (The dudes who will be using the application) about. If I am coding something because of something that they have mentioned, it should be in the domain namespace, and whenever I code something that they have not mentioned (like logging, tracing errors etc) it should NOT be in the domain namespace.

Because of this I am also wary about making too complicated object hierarchies. Ideally a somewhat simplified drawing of the domain model should be intuitively understandable by non-coders.

To this end I don't normally start out by thinking about patterns in much detail. I try to model the domain as simple as I can get away with, following just standard object-oriented design guidelines. What needs to be an object? How are they related?

DDD in my mind is about handling complex software, but if your software is not itself very complex to begin with you could easily end up in a situation where the DDD way of doing things adds complexity rather than removes it.

Once you have a certain level of complexity in your model you will start to see how certain things should be organised, and then you will know which patterns to use, which classes are aggregates etc.

In my example, Myapp.Domain.Sales.Order would be an aggregate root in the sense that when it is instanced it will likely contain other objects, such as a customer object and collection of order lines, and you would only access the order lines for that particular order through the order object.

However, in order to keep things simple, I would not have a "master" object that only contains everything else and has no other purpose, so the order class will itself have values and properties that are useful in the application.

So I will reference things like:

Myapp.Domain.Sales.Order.TotalCost

Myapp.Domain.Sales.Order.OrderDate

Myapp.Domain.Sales.Order.Customer.PreferredInvoiceMethod

Myapp.Domain.Sales.Order.Customer.Address.Zip

etc.

Console
  • 981
  • 7
  • 14
  • Makes sense...Order and Customer are you AggRoots right? So when you reference your Order object you have to do it like: Myapp.Domain.Sales.Order.Order?? –  Feb 10 '09 at 01:27
  • Yes and no - I extended my example a little, as the comments section is a bit too short. – Console Feb 10 '09 at 10:00
  • `Manager` classes in `Data` namespace make me thing of anaemic model – Alexey Zimarev Oct 27 '16 at 17:49
  • This is not a DDD. Where is infrastructure and independent layers idea? – Zon Feb 20 '20 at 18:57
  • @Console, your explanation sounds indeed very practical! it would be very nice if you have a reference to this source code in public repo – Victor Feb 14 '21 at 12:49
5

I like having the domain in the root namespace of the application, in its own assembly:

Acme.Core.dll [root namespace: Acme]

This neatly represents the fact that the domain is in scope of all other portions of the application. (For more, see The Onion Architecture by Jeffrey Palermo).

Next, I have a data assembly (usually with NHibernate) that maps the domain objects to the database. This layer implements repository and service interfaces:

Acme.Data.dll [root namespace: Acme.Data]

Then, I have a presentation assembly declaring elements of my UI-pattern-of-choice:

Acme.Presentation.dll [root namespace: Acme.Presentation]

Finally, there is the UI project (assuming a web app here). This is where the composition of the elements in preceding layers takes place:

Acme.Web [root namespace: Acme.Web]

Bryan Watts
  • 42,403
  • 15
  • 78
  • 85
3

Although you're also a .Net developer, the Java implementation reference of the cargo app from DDD by Eric Evans and Citerus is a good resource.

In the doc'd code, you can see the DDD-organization into bounded contexts and aggregates in action, right in the Java packages.

Additionally, you might consider Billy McCafferty's Sharp Architecture. It's an ASP.Net MVC, NHibernate/Fluent NHibernate implementation that is built with DDD in mind.

Admittedly, you will still need to apply a folder/namespace solution to provide the contexts. But, couple the Evans approach with #Arch and you should be well on your way.

Let us know what you are going with. I am on the same path as well, and not far from you!

Happy coding,

Kurt Johnson

Kurt Johnson
  • 414
  • 5
  • 13
  • UPDATE: I should add that the Who-Can-Help-Me (WCHM) fork of Sharp Architecture. As of September 2010, the WCHM maintainers have been included on the contributor team for Sharp. WCHM reorganizes the Sharp Visual Studio project into Solution folders which explicitly refer to DDD concepts. There are folders for domain (Domain and domain-specific Infrastructure), presentation (web views and web controllers), framework (code considered reusable across domains, and a services layer (Tasks). Future versions of Sharp Architecture are expected to reflect this approach. – Kurt Johnson Nov 04 '10 at 15:25
1

Your domain probably have a name, so you should use this name as namespace.

I usally put repository implementation and data access details in a namespace called Persistance under the domain namespace.

The application use its own name as namespace.

thinkbeforecoding
  • 6,420
  • 1
  • 27
  • 31
0

I'd check out codecampserver since the setup there is quite common.

They have a core project in which they include both the application and domain layers. I.e. the insides of the onion (http://jeffreypalermo.com/blog/the-onion-architecture-part-1/).

I actually like to break the core apart into separate projects to control the direction of dependency. So typically I have:

MyNamespace.SomethingWeb <-- multiple UIs
MyNamespace.ExtranetWeb <-- multiple UIs

MyNamespace.Application <-- Evans' application layer with classes like CustomerService
MyNamespace.Domain

  • MyNamespace.Domain.Model <-- entities
  • MyNamespace.Domain.Services <-- doman services
  • MyNamespace.Domain.Repositories

MyNamespace.Infrastructure <-- repo implementation etc.

MyNamespace.Common <-- A project which all other projects have a dependency to which has things like a Logger, Util classes, etc.

Dinah
  • 48,876
  • 29
  • 126
  • 149
pondermatic
  • 6,147
  • 8
  • 44
  • 57