implementing ddd with c#

24
Implementing DDD with C# Pascal Laurin May 2015 @plaurin78 [email protected] www.pascallaurin.com Microsoft C# MVP MSDEVMTL user group organizer Developer & Architect at GSoft

Upload: pascal-laurin

Post on 17-Jul-2015

793 views

Category:

Technology


6 download

TRANSCRIPT

Page 1: Implementing DDD with C#

Implementing DDD with C#Pascal Laurin

May 2015

@[email protected]

www.pascallaurin.com

Microsoft C# MVPMSDEVMTL user group organizerDeveloper & Architect at GSoft

Page 2: Implementing DDD with C#

DDD Basics

Overall Architecture

Some Design Patterns to help

Questions

Agenda

Page 3: Implementing DDD with C#

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

Page 4: Implementing DDD with C#

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

Page 5: Implementing DDD with C#

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; }

}

Page 6: Implementing DDD with C#

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){}

}

Page 7: Implementing DDD with C#

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();}

}

Page 8: Implementing DDD with C#

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();

}

Page 9: Implementing DDD with C#

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

Page 10: Implementing DDD with C#

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

AP

IA

dapte

r

HR

Payroll

Prep

Employee

Payroll (external)

?

Page 11: Implementing DDD with C#

Hexagonal architecture or Port and Adapter

Domain at the center

Demo solution

The overall architecture

Page 12: Implementing DDD with C#

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

ServicesPorts

Adapters

Page 13: Implementing DDD with C#

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

Page 14: Implementing DDD with C#

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

StubsPorts

Adapters

Page 15: Implementing DDD with C#

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

Page 16: Implementing DDD with C#

Demo Solution

Page 17: Implementing DDD with C#

Interfaces and abstractions

Dependency injection

Bootstrapper

MVC, MVVM, MVP (UI)

Command & Query responsibility segregation

Design Patterns (and Architectural Patterns)

Page 18: Implementing DDD with C#

Most useful to mock dependencies

Swap implementations by configuration

Do not overuse!

Interfaces and abstractions

ISomething

Implementation Mock

Page 19: Implementing DDD with C#

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

Page 20: Implementing DDD with C#

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

Page 21: Implementing DDD with C#

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)

Page 22: Implementing DDD with C#

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

Page 23: Implementing DDD with C#

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

Page 24: Implementing DDD with C#

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

[email protected]

www.pascallaurin.com

Questions?