SlideShare a Scribd company logo
Implementing DDD with C#
Pascal Laurin
May 2015
@plaurin78
pascal.laurin@outlook.com
www.pascallaurin.com
Microsoft C# MVP
MSDEVMTL user group organizer
Developer & Architect at GSoft
DDD Basics
Overall Architecture
Some Design Patterns to help
Questions
Agenda
Model-Driven Design and the Ubiquitous Language
Entities, Value Objects and Services
Aggregates
Factories
Repositories
Bounded Contexts and Context Map
Anticorruption Layers
Domain Driven Design Basics
Technology should have nothing to do with domain modeling of a
system
Put the domain at the center of the solution
Should use the domain language even in code (at the lowest level:
variable names)
Only one word per concept!
Use ULM if you like but simple diagrams should work too
User stories, use cases, etc.
Model-Driven Design and the Ubiquitous
Language
Order
Order line Product
* 1
Entities have identities
Value Objects don’t have identities (mostly immutable)
Use services only with complex operations requiring multiples
domain entities
Some team use services with anemic entities (better fit for functional
languages?)
Entities, Value Objects and Services
public class Money // Value Object
{
public decimal Amount { get; private set; }
public Currency Currency { get; private set; }
}
public class Product // Entity
{
public int Id { get; private set; }
public string Description { get; private set; }
}
Boundary around objects inside (can't access objects directly, must
go through the Root)
Enforce invariants of the Entities inside
Root Entity has global identity
Internal Entities have local identities
Contains no direct references to other Aggregates, only IDs
Aggregates
public class Product // Aggregate root
{
public int Id { get; private set; }
public int CatalogId { get; private set; }
public Money Price { get; private set; }
public void ChangePrice(Money newPrice)
{
}
}
For creation and initialization of complex objects structures
Respect invariants
Creation as an atomic unit (complete or fail, no partial)
Creates entire Aggregates
Can use simple constructor on Aggregate Root Entity if construction
is simple enough
Factories
public class ProductFactory
{
public Product CreatePhysicalProduct(string name, Weight weight,
Dimensions dimensions)
{
return new Product();
}
public Product CreateDigitalProduct(string name, StorageSize storageSize)
{
return new DigitalProduct();
}
}
Don’t use generic Repository<T>!
Don’t leak DAL concerns in the domain
Most DAL technology today already offer a generic abstraction
Mostly for mocking with unit testing
Repositories
public interface IProductRepository
{
Product LoadProductAggregateById(int id);
void AddNewProduct(Product product);
IEnumerable<Product> QueryProductsByCatalog(string catalogName);
IEnumerable<Product> QueryArchivedProducts(string catalogName);
IEnumerable<Product> QueryDiscountedProducts(string nameFilter,
DateTime? discountExpirationDateFilter, Money maxPriceFilter);
IQueryable<Product> GetById(int id);
IQueryable<Product> GetAll();
}
Split large domains into smaller ones
Especially if two vision of the same domain concept dependent of the
view point
Usually along departments or divisions lines, business units, etc.
Could be still be monolithic apps or separated apps
Bounded Contexts and Context Map
HR
Payroll
Employee
Security
Access
Control
Employee
Don’t pollute your domain with foreign concepts
Abstract external providers, partners, etc.
Translate between two different domains (Bounded Context) using
Adapters
Allow both to evolve independently
Anticorruption Layers
API
Adapter
HR
Payroll
Prep
Employee
Payroll (external)
?
Hexagonal architecture or Port and Adapter
Domain at the center
Demo solution
The overall architecture
Ports are API or contracts in and out of the domain
Adapters translate between Ports and external dependencies
Swap out external dependencies implementation using different
adapters or using mocks
Hexagonal architecture or Port and
Adapter
Domain
UI
API
Data Store
External
Services
Ports
Adapters
Push everything to the sides and concentrate on the middle
For big app components => Hexagonal architecture to split into
smaller chunk
Either monolithic app or micro-services
The Domain at the center of everything
Only testing the Domain
Testing at the Ports entering the Domain
Use mocks or stubs to replace the Adapters
14
Unit Tests
Domain
Unit Test
Mocks or
Stubs
Ports
Adapters
Only testing the Adapters
Testing at the Ports exiting the Domain
Adapters calling real external dependencies
15
Integration Tests
Domain
Integration
Test
Real external
dependencies
Ports
Adapters
Demo Solution
Interfaces and abstractions
Dependency injection
Bootstrapper
MVC, MVVM, MVP (UI)
Command & Query responsibility segregation
Design Patterns (and Architectural
Patterns)
Most useful to mock dependencies
Swap implementations by configuration
Do not overuse!
Interfaces and abstractions
ISomething
Implementation Mock
Inversion of Control
Domain should not depend on DAL, Web Services, IO, etc.
Construction, composition and life cycle of non-domain concerns stay
outside the domain (use Factories for domain objects)
Dependency injection
Presentation
Business
Data
Application startup code
Composition of the application, services and infrastructure code
Load configuration and setup
Should help write integration tests by replacing some external
dependencies in the tests
Bootstrapper
Presentation patterns
Mostly useful when unit testing and reuse if multiple platforms
targeting (mobile)
Model and View always separated
MVC, MVVM, MVP (UI)
View Controller
Model
Web site, web service, API
View ViewModel
Model
Desktop, SPA (data binding)
View Presenter
Model
Desktop (no data binding)
Queries are simple and have no side effect
All changes to entities go through commands
With CommandHandler to execute Command
Could still be using the same data store for both Command and
Query
Command Dispatcher
Command & Query Responsibility
Segregation
Presentation
Read
Repository
Read
DB
Write
Repository
CommandHandler
Write
DB
Controller
or API
Domain
Domain Driven Development improve the quality of the code by
Introducing useful design patterns to structure your application
Knowing where each piece of new code should go
Better communication by using the language of the domain in the team
Clear separation of business and non-business code
24
Conclusion
References
DDD book by Eric Evans
• http://www.amazon.ca/dp/0321125215
DDD Quickly
• http://www.infoq.com/minibooks/domain-driven-design-quickly
SlideShare of the presentation
• http://www.slideshare.net/PascalLaurin
BitBucket for the code
• https://bitbucket.org/pascallaurin/ddd-talk
@plaurin78
pascal.laurin@outlook.com
www.pascallaurin.com
Questions?

More Related Content

Implementing DDD with C#

  • 1. Implementing DDD with C# Pascal Laurin May 2015 @plaurin78 pascal.laurin@outlook.com www.pascallaurin.com Microsoft C# MVP MSDEVMTL user group organizer Developer & Architect at GSoft
  • 2. DDD Basics Overall Architecture Some Design Patterns to help Questions Agenda
  • 3. Model-Driven Design and the Ubiquitous Language Entities, Value Objects and Services Aggregates Factories Repositories Bounded Contexts and Context Map Anticorruption Layers Domain Driven Design Basics
  • 4. Technology should have nothing to do with domain modeling of a system Put the domain at the center of the solution Should use the domain language even in code (at the lowest level: variable names) Only one word per concept! Use ULM if you like but simple diagrams should work too User stories, use cases, etc. Model-Driven Design and the Ubiquitous Language Order Order line Product * 1
  • 5. Entities have identities Value Objects don’t have identities (mostly immutable) Use services only with complex operations requiring multiples domain entities Some team use services with anemic entities (better fit for functional languages?) Entities, Value Objects and Services public class Money // Value Object { public decimal Amount { get; private set; } public Currency Currency { get; private set; } } public class Product // Entity { public int Id { get; private set; } public string Description { get; private set; } }
  • 6. Boundary around objects inside (can't access objects directly, must go through the Root) Enforce invariants of the Entities inside Root Entity has global identity Internal Entities have local identities Contains no direct references to other Aggregates, only IDs Aggregates public class Product // Aggregate root { public int Id { get; private set; } public int CatalogId { get; private set; } public Money Price { get; private set; } public void ChangePrice(Money newPrice) { } }
  • 7. For creation and initialization of complex objects structures Respect invariants Creation as an atomic unit (complete or fail, no partial) Creates entire Aggregates Can use simple constructor on Aggregate Root Entity if construction is simple enough Factories public class ProductFactory { public Product CreatePhysicalProduct(string name, Weight weight, Dimensions dimensions) { return new Product(); } public Product CreateDigitalProduct(string name, StorageSize storageSize) { return new DigitalProduct(); } }
  • 8. Don’t use generic Repository<T>! Don’t leak DAL concerns in the domain Most DAL technology today already offer a generic abstraction Mostly for mocking with unit testing Repositories public interface IProductRepository { Product LoadProductAggregateById(int id); void AddNewProduct(Product product); IEnumerable<Product> QueryProductsByCatalog(string catalogName); IEnumerable<Product> QueryArchivedProducts(string catalogName); IEnumerable<Product> QueryDiscountedProducts(string nameFilter, DateTime? discountExpirationDateFilter, Money maxPriceFilter); IQueryable<Product> GetById(int id); IQueryable<Product> GetAll(); }
  • 9. Split large domains into smaller ones Especially if two vision of the same domain concept dependent of the view point Usually along departments or divisions lines, business units, etc. Could be still be monolithic apps or separated apps Bounded Contexts and Context Map HR Payroll Employee Security Access Control Employee
  • 10. Don’t pollute your domain with foreign concepts Abstract external providers, partners, etc. Translate between two different domains (Bounded Context) using Adapters Allow both to evolve independently Anticorruption Layers API Adapter HR Payroll Prep Employee Payroll (external) ?
  • 11. Hexagonal architecture or Port and Adapter Domain at the center Demo solution The overall architecture
  • 12. Ports are API or contracts in and out of the domain Adapters translate between Ports and external dependencies Swap out external dependencies implementation using different adapters or using mocks Hexagonal architecture or Port and Adapter Domain UI API Data Store External Services Ports Adapters
  • 13. Push everything to the sides and concentrate on the middle For big app components => Hexagonal architecture to split into smaller chunk Either monolithic app or micro-services The Domain at the center of everything
  • 14. Only testing the Domain Testing at the Ports entering the Domain Use mocks or stubs to replace the Adapters 14 Unit Tests Domain Unit Test Mocks or Stubs Ports Adapters
  • 15. Only testing the Adapters Testing at the Ports exiting the Domain Adapters calling real external dependencies 15 Integration Tests Domain Integration Test Real external dependencies Ports Adapters
  • 17. Interfaces and abstractions Dependency injection Bootstrapper MVC, MVVM, MVP (UI) Command & Query responsibility segregation Design Patterns (and Architectural Patterns)
  • 18. Most useful to mock dependencies Swap implementations by configuration Do not overuse! Interfaces and abstractions ISomething Implementation Mock
  • 19. Inversion of Control Domain should not depend on DAL, Web Services, IO, etc. Construction, composition and life cycle of non-domain concerns stay outside the domain (use Factories for domain objects) Dependency injection Presentation Business Data
  • 20. Application startup code Composition of the application, services and infrastructure code Load configuration and setup Should help write integration tests by replacing some external dependencies in the tests Bootstrapper
  • 21. Presentation patterns Mostly useful when unit testing and reuse if multiple platforms targeting (mobile) Model and View always separated MVC, MVVM, MVP (UI) View Controller Model Web site, web service, API View ViewModel Model Desktop, SPA (data binding) View Presenter Model Desktop (no data binding)
  • 22. Queries are simple and have no side effect All changes to entities go through commands With CommandHandler to execute Command Could still be using the same data store for both Command and Query Command Dispatcher Command & Query Responsibility Segregation Presentation Read Repository Read DB Write Repository CommandHandler Write DB Controller or API Domain
  • 23. Domain Driven Development improve the quality of the code by Introducing useful design patterns to structure your application Knowing where each piece of new code should go Better communication by using the language of the domain in the team Clear separation of business and non-business code 24 Conclusion
  • 24. References DDD book by Eric Evans • http://www.amazon.ca/dp/0321125215 DDD Quickly • http://www.infoq.com/minibooks/domain-driven-design-quickly SlideShare of the presentation • http://www.slideshare.net/PascalLaurin BitBucket for the code • https://bitbucket.org/pascallaurin/ddd-talk @plaurin78 pascal.laurin@outlook.com www.pascallaurin.com Questions?

Editor's Notes

  1. Show the projects (dependencies if not already done) First level in Business, Data and Presentation are domain concepts First level in Application and Infrastructure are non-domain concepts One test project per type: unit, integration, system, behaviour or functional
  2. Graph ou code?