Slide 1

Slide 1 text

DDD with OrigoDB @robertfriberg [email protected] origodb.com

Slide 2

Slide 2 text

What is DDD? • Focus on the domain – model driven design • Ubiquitous language – same lingo across disciplines • Patterns • Aggregates • Entity objects • Value objects • Domain Events • Services • Repository

Slide 3

Slide 3 text

Why? Service Layer Domain Layer Data Access Layer Relational Model Views/SP’s Build faster systems faster

Slide 4

Slide 4 text

One simple idea... Keep state in memory Persist operations, not system state s0 s1 s2 op1 op2 Sn = apply(opn , Sn-1 )

Slide 5

Slide 5 text

... with many names • ARIES – write ahead logging (WAL) • System prevalance – Prevalyer, java • MongoDB op log • Redis AOF • Memory Image – Martin Fowler • VoltDB – command logging • Akka persistence – logging per actor • Event Sourcing – Greg Young et al

Slide 6

Slide 6 text

OrigoDB Kernel Engine Model Storage App Code Server Command Query File Sql Event Store Custom Consistency Isolation concurrency Sends commands and queries Journaling Snapshots BinaryFormatter ProtoBuf JSON tcp JSON/http In-process calls Domain specific object-graph Domain specific operations Replication Ad-hoc queries Web ui Console or win svc

Slide 7

Slide 7 text

Example – the model [Serializable] public class CommerceModel : Model { internal SortedDictionary Customers { get; set; } internal SortedDictionary Orders { get; set; } internal SortedDictionary Products { get; set; } public CommerceModel() { Customers = new SortedDictionary(); Orders = new SortedDictionary(); Products = new SortedDictionary(); } }

Slide 8

Slide 8 text

Command [Serializable] public class AddCustomer : Command { public readonly Guid Id; public readonly string Name; public AddCustomer(Guid id, String name) { Id = id; Name = name; } public override void Execute(CommerceModel model) { if (model.Customers.ContainsKey(Id)) Abort("Duplicate customer id"); var customer = new Customer {Id = Id, Name = Name}; model.Customers.Add(Id, customer); } }

Slide 9

Slide 9 text

Query [Serializable] public class CustomerById : Query { public readonly Guid Id; public CustomerById(Guid id) { Id = id; } public override CustomerView Execute(CommerceModel model) { if (!model.Customers.ContainsKey(Id)) throw new Exception("no such customer"); return new CustomerView(model.Customers[Id]); } }

Slide 10

Slide 10 text

Start your engines! static void Main(string[] args) { Guid id = Guid.NewGuid(); var engine = Engine.For(); var customerCommand = new AddCustomer(id, "Homer"); engine.Execute(customerCommand); var customerView = engine.Execute(new CustomerById(id)); Console.WriteLine(customerView.Name); Console.WriteLine("{0} orders", customerView.OrderIds.Count); Console.ReadLine(); }

Slide 11

Slide 11 text

DDD < - > OrigoDb Aggregates Entity Objects Value Objects Domain Events Services Bounded Context Model POCO NET Events Commands Repository

Slide 12

Slide 12 text

Thank you! • Questions? • Try it, you’ll like it! • Feedback – tell me what you think • Contribute! • http://origodb.com • @robertfriberg, [email protected]

Slide 13

Slide 13 text

The model is an object graph TaskList Task Task Task TaskList Task Task Task Task Category Category Category Category TaskModel

Slide 14

Slide 14 text

x64 vs. x32 • Core Library compiled with AnyCPU • x32 = 32-bit pointers, max 4GB • x64 = 64-bit pointers • Server ships with x64 and x32 binaries

Slide 15

Slide 15 text

IIS Hosting • Disable application pool recycling • Ensure single process, no farming or LB • Litter controllers with Db.For() / Engine.For() • Or put a static ref somewhere, eg Global.asax

Slide 16

Slide 16 text

Implicit operations • Proxy has same interface as the Model • Method calls are intercepted • void methods interpreted as commands (and logged) • other methods interpreted as queries • Can be overriden with attributes • Local or remote, cluster

Slide 17

Slide 17 text

Example static void ProxyExample(IEngine engine) { CommerceModel proxy = engine.GetProxy(); proxy.AddProduct(Guid.NewGuid(), "Duff beer", 40, 2.5M); var customers = proxy.Customers.Values .Where(c => c.Name.StartsWith("H")) .Select(c => new CustomerView(c)).ToList(); foreach (var customer in customers) { Console.WriteLine(customer.Name); } }

Slide 18

Slide 18 text

Immutable models writer reader

Slide 19

Slide 19 text

Example immutable model

Slide 20

Slide 20 text

Example immutable entity

Slide 21

Slide 21 text

Immutable command example

Slide 22

Slide 22 text

Configuration