Print this page Share

.NET Domain-Driven Design with C#: Problem - Design - Solution

ISBN: 978-0-470-14756-6
432 pages
April 2008
.NET Domain-Driven Design with C#: Problem - Design - Solution (0470147563) cover image


As the first technical book of its kind, this unique resource walks you through the process of building a real-world application using Domain-Driven Design implemented in C#. Based on a real application for an existing company, each chapter is broken down into specific modules so that you can identify the problem, decide what solution will provide the best results, and then execute that design to solve the problem. With each chapter, you'll build a complete project from beginning to end.
See More

Table of Contents

Acknowledgments xv

Introduction xvii

Chapter 1: Introducing the Project: The SmartCA Application 1

The Problem 1

The Design 4

Reliability and Availability 4

Scalability 5

Maintainability 5

Rich Client Application Functionality 5

Offline Capable 5

Web Access 5

Intelligent Installation and Auto-Update Functionality 5

Additional Client Device Support 5

The Solution 6

Fulfilling the Reliability, Availability, Scalability, Offline Capable, and Additional Client Device Support Requirements 6

Fulfilling the Maintainability Requirement 7

Fulfilling the Rich Client Application Functionality Requirement 9

Fulfilling the Web Access Requirement 11

Fulfilling the Intelligent Installation and Auto-Update Functionality Requirement 11

Summary 11

Chapter 2: Designing the Layered Architecture 13

The Problem 13

The Design 13

Designing the Visual Studio Solution 13

Designing the Architectural Layers 14

The Solution 18

Implementing the Visual Studio Solution 19

Implementing the Architectural Layers 19

Summary 53

Chapter 3: Managing Projects 55

The Problem 55

The Design 55

Designing the Domain Model 56

Defining the Project Aggregate 56

Defining the Aggregate Boundaries 57

Designing the Repositories 58

Writing the Unit Tests 60

The Solution 65

The Project Class 65

The Repository Implementations 77

The Service Class Implementations 90

The Project Information ViewModel Implementation 92

The Project Information View Implementation 102

Summary 107

Chapter 4: Companies and Contacts 109

The Problem 109

The Design 109

Designing the Domain Model 110

Defining the Company and Contact Aggregates 110

Defining the Aggregate Boundaries 111

Designing the Repositories 112

Writing the Unit Tests 114

The Solution 119

The Company Class 119

The Contact Class 121

The ProjectContact Class 123

The Repository Implementations 124

The Service Class Implementations 134

The Company ViewModel 137

The Company View 144

The Project Contact View Model 148

The Project Contact View 154

Summary 156

Chapter 5: Submittal Transmittals 157

The Problem 157

The Design 158

Designing the Domain Model 158

Defining the Submittal Aggregate 159

Defining the Aggregate Boundaries 159

Designing the Repository 160

Writing the Unit Tests 161

The Solution 164

The Submittal Repository Implementation 178

The Submittal Service Implementation 187

The Submittal View Model 188

The Submittal View 192

Summary 197

Chapter 6: Requests for Information 199

The Problem 199

The Design 200

Designing the Domain Model 200

Defining the RFI Aggregate 201

Defining the Aggregate Boundaries 202

Designing the Repository 203

Writing the Unit Tests 204

The Solution 207

The RFI Repository Implementation 213

The RFI Service Implementation 223

The RFI ViewModel Classes 224

The RFI View 231

Summary 232

Chapter 7: Proposal Requests 233

The Problem 233

The Design 234

Designing the Domain Model 234

Designing the Proposal Request Aggregate 235

Defining the Aggregate Boundaries 236

Designing the Repository 237

Writing the Unit Tests 239

The Solution 242

The Proposal Request Class Private Fields and Constructors 242

The ProposalRequest Properties 245

The Validate Method 248

The Proposal Request Repository Implementation 253

The Proposal Request Service Implementation 257

The Proposal Request View Model Class 258

The Proposal Request View 260

Summary 263

Chapter 8: Change Orders 265

The Problem 265

The Design 266

Designing the Domain Model 266

Designing the Change Order Aggregate 267

Defining the Aggregate Boundaries 268

Designing the Repository 268

Writing the Unit Tests 271

The Solution 271

The Change Order Repository Implementation 283

The Change Order Service Implementation 288

The Change Order View Model Class 289

The Change Order View 292

Summary 293

Chapter 9: Construction Change Directives 295

The Problem 295

The Design 295

Designing the Domain Model 296

Designing the Construction Change Directive Aggregate 297

Defining the Aggregate Boundaries 298

Designing the Repository 299

Writing the Unit Tests 300

The Solution 300

The Construction Change Directive Class Private Fields and Constructors 300

The Construction Change Directive Repository Implementation 307

The Construction Change Directive Service Implementation 313

The Construction Change Directive ViewModel Class 314

The Construction Change Directive View 324

Summary 325

Chapter 10: Synchronizing With the Server 327

The Problem 327

The Design 327

Redesigning the Unit of Work 328

Designing the Synchronization 330

Writing the Unit Tests 331

The Solution 333

Unit of Work Refactoring 333

Synchronizing with the Synchronizer Class 349

Summary 356

Chapter 11: The Client Membership System 357

The Problem 357

The Design 357

Password Security 358

Designing the Client Membership System 358

The Solution 359

The Client Membership System Domain Model Classes 360

Client Membership System Unit Tests 388

Summary 389

Index 391

See More

Author Information

Tim McCarthy is a freelance consultant who architects, designs and builds highly scalable layered web and smart client applications utilizing the latest Microsoft platforms and technologies. Tim is a Microsoft MVP in Solutions Architecture, and his expertise covers a wide range of Microsoft technologies, including, but not limited to, the following: .NET Framework (ASP.NET/Smart Clients/VSTO/Workflow/Web Services, Windows Presentation Foundation), SQL Server, Active Directory, MS Exchange development, UDDI, SharePoint, and Service Oriented Architecture (SOA) applications.
Tim has worked as both a project technical lead/member as well as being in a technical consulting role for several Fortune 500 companies. He has held the Microsoft Certified Solution Developer (MCSD) and Microsoft Certified Trainer (MCT) certifications for several years, and was one of the first wave of developers to earn the Microsoft Certified Application Developer (MCAD) for .NET and MCSD for .NET certifications. He also holds the Microsoft Certified Database Administrator certification for SQL Server 2000. Tim is also certified as an IEEE Certified Software Development Professional, and he is one of only 550 people to hold this certification in the world.
Tim has been an author and technical reviewer for several books from Wrox Press. His other books include being a lead author on Professional VB 2005 , several editions of Professional VB.NET , Professional Commerce Server 2000 , and Professional ADO 2.5 Programming . He also has written and presented a DVD titled SharePoint Portal Services Programming 2003 . Tim has written numerous articles for the Developer .NET Update newsletter, developed packaged presentations for the Microsoft Developer Network (MSDN), and wrote a whitepaper for Microsoft on using COM+ services in .NET. He has also written articles for SQL Server Magazine and Windows & .NET Magazine.
See More


Download TitleSizeDownload
Read Me File 454 bytes Click to Download
Chapter 2 Code 3.66 MB Click to Download
Chapter 3 Code 9.05 MB Click to Download
Chapter 4 Code 13.17 MB Click to Download
Chapter 5 Code 7.43 MB Click to Download
Chapter 6 Code 1.66 MB Click to Download
Chapter 7 Code 2.88 MB Click to Download
Chapter 8 Code 4.06 MB Click to Download
Chapter 9 Code 1.66 MB Click to Download
Chapter 10 Code 1.62 MB Click to Download
Chapter 11 Code 1.88 MB Click to Download
Code Download at codeplex.com 119 bytes Click to Download
See More


Do you think you've discovered an error in this book? Please check the list of errata below to see if we've already addressed the error. If not, please submit the error via our Errata Form. We will attempt to verify your error; if you're right, we will post a correction below.

ChapterPageDetailsDatePrint Run
22 Code Correction
In the GetHashCode() method in the code listing,
the key may be null and should therefore be
checked before invoking its GetHashCode()
32-33 Error in Code Example
The code sample should look like this: using System; using System.Collections.Generic; using SmartCA.Infrastructure.DomainBase; using SmartCA.Infrastructure.RepositoryFramework; using System.Transactions; namespace SmartCA.Infrastructure { public class UnitOfWork : IUnitOfWork { private Dictionary<EntityBase, IUnitOfWorkRepository> addedEntities; private Dictionary<EntityBase, IUnitOfWorkRepository> changedEntities; private Dictionary<EntityBase, IUnitOfWorkRepository> deletedEntities; public UnitOfWork() { this.addedEntities = new Dictionary<EntityBase, IUnitOfWorkRepository>(); this.changedEntities = new Dictionary<EntityBase, IUnitOfWorkRepository>(); this.deletedEntities = new Dictionary<EntityBase, IUnitOfWorkRepository>(); } #region IUnitOfWork Members public void RegisterAdded(EntityBase entity, IUnitOfWorkRepository repository) { this.addedEntities.Add(entity, repository); } public void RegisterChanged(EntityBase entity, IUnitOfWorkRepository repository) { this.changedEntities.Add(entity, repository); } public void RegisterRemoved(EntityBase entity, IUnitOfWorkRepository repository) { this.deletedEntities.Add(entity, repository); } public void Commit() { using (TransactionScope scope = new TransactionScope()) { foreach (EntityBase entity in this.deletedEntities.Keys) { this.deletedEntities[entity].PersistDeletedItem(entity); } foreach (EntityBase entity in this.addedEntities.Keys) { this.addedEntities[entity].PersistNewItem(entity); } foreach (EntityBase entity in this.changedEntities.Keys) { this.changedEntities[entity].PersistUpdatedItem(entity); } scope.Complete(); } this.deletedEntities.Clear(); this.addedEntities.Clear(); this.changedEntities.Clear(); } #endregion } } the actual code files for the chapter are correct
33 Reference Correction
The reference to the Nilsson book in the third
section of the Unity of Work chapter has a
incomplete year (200).
33-35 Error in Code Example
the second code example code should look like this: using System; using SmartCA.Infrastructure.DomainBase; using System.Collections.Generic; namespace SmartCA.Infrastructure.RepositoryFramework { public abstract class RepositoryBase<T> : IRepository<T>, IUnitOfWorkRepository where T : EntityBase { private IUnitOfWork unitOfWork; protected RepositoryBase() : this(null) { } protected RepositoryBase(IUnitOfWork unitOfWork) { this.unitOfWork = unitOfWork; } #region IRepository<T> Members public abstract T FindBy(object key); public abstract IList<T> FindAll(); public void Add(T item) { if (this.unitOfWork != null) { this.unitOfWork.RegisterAdded(item, this); } } public void Remove(T item) { if (this.unitOfWork != null) { this.unitOfWork.RegisterRemoved(item, this); } } public T this[object key] { get { return this.FindBy(key); } set { if (this.FindBy(key) == null) { this.Add(value); } else { if (this.unitOfWork != null) { this.unitOfWork.RegisterChanged(value, this); } } } } #endregion #region IUnitOfWorkRepository Members public void PersistNewItem(EntityBase item) { this.PersistNewItem((T)item); } public void PersistUpdatedItem(EntityBase item) { this.PersistUpdatedItem((T)item); } public void PersistDeletedItem(EntityBase item) { this.PersistDeletedItem((T)item); } #endregion protected abstract void PersistNewItem(T item); protected abstract void PersistUpdatedItem(T item); protected abstract void PersistDeletedItem(T item); } } the actual code file for the chapter is correct
44 Error in Text
First line under heading "The EntityFactoryBuilder Class":


should be:
IEntityFactory<T> instances
4 109 Error in Text
In the next few sections, I will be designing the domain model, determining the Project Aggregate and its boundaries, and designing the repository for Projects.

should be:
In the next few sections, I will be designing the domain model, determining the aggregates and their boundaries, and designing the repositories for Companies and Contacts".
173 Code Correction
The code listing on page 173 should now look like this:

using System;
using SmartCA.Model.Projects;
namespace SmartCA.Model.Submittals
public class TrackingItem
private SpecificationSection specSection;
private int totalItemsReceived;
private int totalItemsSent;
private int deferredApproval;
private int substitutionNumber;
private string description;
private ActionStatus status;

public TrackingItem(SpecificationSection specSection)
this.specSection = specSection;
this.totalItemsReceived = 0;
this.totalItemsSent = 0;
this.deferredApproval = 0;
this.description = string.Empty;
this.status = ActionStatus.NoExceptionTaken;

public SpecificationSection SpecSection
get { return this.specSection; }
set { this.specSection = value; }

public int TotalItemsReceived
get { return this.totalItemsReceived; }
if (value != this.totalItemsReceived) { this.totalItemsReceived = value;
// Default to making the total number
// of items sent equal to what was received
this.totalItemsSent = value;

public int TotalItemsSent
get { return this.totalItemsSent; }
set { this.totalItemsSent = value; }

public int DeferredApproval
get { return this.deferredApproval; }
set { this.deferredApproval = value; }

public int SubstitutionNumber
get { return this.substitutionNumber; }
set { this.substitutionNumber = value; }

public string Description
get { return this.description; }
set { this.description = value; }

public ActionStatus Status
get { return this.status; }
set { this.status = value; }
See More

Related Titles

Back to Top