Repository: looplab/eventhorizon
Pull request #315 (2021-04-30 12:39:32)

Feature / UUID alias type
### Description

Add UUID alias type for easier replacement of the whole UUID package. A fork of Event Horizon only needs to provide the functions inside the uuid package. This seems to be the next-best solution to have configurable ID types until generic lands.

### Affected Components

- UUID type

### Related Issues

### Solution and Design

### Steps to test and verify



Patch:
diff --git a/aggregate.go b/aggregate.go
index 7991dc0..147538c 100644
--- a/aggregate.go
+++ b/aggregate.go
@@ -20,7 +20,7 @@ import (
 	"fmt"
 	"sync"
 
-	"github.com/google/uuid"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 // Aggregate is an interface representing a versioned data entity created from
diff --git a/codec/bson/codec.go b/codec/bson/codec.go
index 15f01f7..738717a 100644
--- a/codec/bson/codec.go
+++ b/codec/bson/codec.go
@@ -19,10 +19,10 @@ import (
 	"fmt"
 	"time"
 
-	"github.com/google/uuid"
 	"go.mongodb.org/mongo-driver/bson"
 
 	eh "github.com/looplab/eventhorizon"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 // EventCodec is a codec for marshaling and unmarshaling events
diff --git a/codec/json/codec.go b/codec/json/codec.go
index 5d8f77a..f0a0f65 100644
--- a/codec/json/codec.go
+++ b/codec/json/codec.go
@@ -20,9 +20,8 @@ import (
 	"fmt"
 	"time"
 
-	"github.com/google/uuid"
-
 	eh "github.com/looplab/eventhorizon"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 // EventCodec is a codec for marshaling and unmarshaling events
diff --git a/command.go b/command.go
index 6c3680c..742d24a 100644
--- a/command.go
+++ b/command.go
@@ -21,7 +21,7 @@ import (
 	"sync"
 	"time"
 
-	"github.com/google/uuid"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 // Command is a domain command that is sent to a Dispatcher.
diff --git a/context.go b/context.go
index 85e2d10..e666a9c 100644
--- a/context.go
+++ b/context.go
@@ -19,7 +19,7 @@ import (
 	"sync"
 	"time"
 
-	"github.com/google/uuid"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 // DefaultNamespace is the namespace to use if not set in the context.
diff --git a/entity.go b/entity.go
index 3a18470..76b024f 100644
--- a/entity.go
+++ b/entity.go
@@ -14,7 +14,7 @@
 
 package eventhorizon
 
-import "github.com/google/uuid"
+import "github.com/looplab/eventhorizon/uuid"
 
 // Entity is an item which is identified by an ID.
 //
diff --git a/event.go b/event.go
index dfc41a6..c5f9675 100644
--- a/event.go
+++ b/event.go
@@ -20,7 +20,7 @@ import (
 	"sync"
 	"time"
 
-	"github.com/google/uuid"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 // Event is a domain event describing a change that has happened to an aggregate.
diff --git a/eventhandler/waiter/eventhandler.go b/eventhandler/waiter/eventhandler.go
index 05ffb6d..e3b1231 100644
--- a/eventhandler/waiter/eventhandler.go
+++ b/eventhandler/waiter/eventhandler.go
@@ -17,8 +17,8 @@ package waiter
 import (
 	"context"
 
-	"github.com/google/uuid"
 	eh "github.com/looplab/eventhorizon"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 // EventHandler waits for certain events to match a criteria.
diff --git a/eventstore.go b/eventstore.go
index e2fb84f..cc6e887 100644
--- a/eventstore.go
+++ b/eventstore.go
@@ -18,7 +18,7 @@ import (
 	"context"
 	"errors"
 
-	"github.com/google/uuid"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 // EventStore is an interface for an event sourcing event store.
diff --git a/eventstore/memory/eventmaintenance.go b/eventstore/memory/eventmaintenance.go
index 6e0c756..b8de4cc 100644
--- a/eventstore/memory/eventmaintenance.go
+++ b/eventstore/memory/eventmaintenance.go
@@ -17,9 +17,8 @@ package memory
 import (
 	"context"
 
-	"github.com/google/uuid"
-
 	eh "github.com/looplab/eventhorizon"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 // Replace implements the Replace method of the eventhorizon.EventStore interface.
diff --git a/eventstore/memory/eventstore.go b/eventstore/memory/eventstore.go
index 361fc35..d08e87f 100644
--- a/eventstore/memory/eventstore.go
+++ b/eventstore/memory/eventstore.go
@@ -20,10 +20,10 @@ import (
 	"fmt"
 	"sync"
 
-	"github.com/google/uuid"
 	"github.com/jinzhu/copier"
 
 	eh "github.com/looplab/eventhorizon"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 var (
diff --git a/eventstore/mongodb/eventstore.go b/eventstore/mongodb/eventstore.go
index 1d72ad1..373e312 100644
--- a/eventstore/mongodb/eventstore.go
+++ b/eventstore/mongodb/eventstore.go
@@ -20,7 +20,6 @@ import (
 	"fmt"
 	"time"
 
-	"github.com/google/uuid"
 	"go.mongodb.org/mongo-driver/bson"
 	"go.mongodb.org/mongo-driver/mongo"
 	mongoOptions "go.mongodb.org/mongo-driver/mongo/options"
@@ -32,6 +31,7 @@ import (
 	_ "github.com/looplab/eventhorizon/codec/bson"
 
 	eh "github.com/looplab/eventhorizon"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 var (
diff --git a/eventstore/tracing/eventstore.go b/eventstore/tracing/eventstore.go
index b4fdecf..95290dc 100644
--- a/eventstore/tracing/eventstore.go
+++ b/eventstore/tracing/eventstore.go
@@ -17,10 +17,11 @@ package tracing
 import (
 	"context"
 
-	"github.com/google/uuid"
-	eh "github.com/looplab/eventhorizon"
 	"github.com/opentracing/opentracing-go"
 	"github.com/opentracing/opentracing-go/ext"
+
+	eh "github.com/looplab/eventhorizon"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 // EventStore is a EventStore that adds tracing.
diff --git a/examples/guestlist/domains/guestlist/aggregate.go b/examples/guestlist/domains/guestlist/aggregate.go
index 05a97bc..981b283 100644
--- a/examples/guestlist/domains/guestlist/aggregate.go
+++ b/examples/guestlist/domains/guestlist/aggregate.go
@@ -20,9 +20,9 @@ import (
 	"log"
 	"time"
 
-	"github.com/google/uuid"
 	eh "github.com/looplab/eventhorizon"
 	"github.com/looplab/eventhorizon/aggregatestore/events"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 func init() {
diff --git a/examples/guestlist/domains/guestlist/commands.go b/examples/guestlist/domains/guestlist/commands.go
index 05d4df2..9fcd26b 100644
--- a/examples/guestlist/domains/guestlist/commands.go
+++ b/examples/guestlist/domains/guestlist/commands.go
@@ -15,8 +15,8 @@
 package guestlist
 
 import (
-	"github.com/google/uuid"
 	eh "github.com/looplab/eventhorizon"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 func init() {
diff --git a/examples/guestlist/domains/guestlist/projectors.go b/examples/guestlist/domains/guestlist/projectors.go
index 5de2794..e2048fd 100644
--- a/examples/guestlist/domains/guestlist/projectors.go
+++ b/examples/guestlist/domains/guestlist/projectors.go
@@ -20,9 +20,9 @@ import (
 	"fmt"
 	"sync"
 
-	"github.com/google/uuid"
 	eh "github.com/looplab/eventhorizon"
 	"github.com/looplab/eventhorizon/eventhandler/projector"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 // Invitation is a read model object for an invitation.
diff --git a/examples/guestlist/domains/guestlist/saga.go b/examples/guestlist/domains/guestlist/saga.go
index fd5dda0..1485ad1 100644
--- a/examples/guestlist/domains/guestlist/saga.go
+++ b/examples/guestlist/domains/guestlist/saga.go
@@ -18,9 +18,9 @@ import (
 	"context"
 	"sync"
 
-	"github.com/google/uuid"
 	eh "github.com/looplab/eventhorizon"
 	"github.com/looplab/eventhorizon/eventhandler/saga"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 // ResponseSagaType is the type of the saga.
diff --git a/examples/guestlist/domains/guestlist/setup.go b/examples/guestlist/domains/guestlist/setup.go
index 8aefa26..2b32b3c 100644
--- a/examples/guestlist/domains/guestlist/setup.go
+++ b/examples/guestlist/domains/guestlist/setup.go
@@ -18,7 +18,6 @@ import (
 	"context"
 	"log"
 
-	"github.com/google/uuid"
 	eh "github.com/looplab/eventhorizon"
 	"github.com/looplab/eventhorizon/aggregatestore/events"
 	"github.com/looplab/eventhorizon/commandhandler/aggregate"
@@ -26,6 +25,7 @@ import (
 	"github.com/looplab/eventhorizon/eventhandler/projector"
 	"github.com/looplab/eventhorizon/eventhandler/saga"
 	"github.com/looplab/eventhorizon/middleware/eventhandler/observer"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 // Setup configures the guestlist.
diff --git a/examples/todomvc/backend/domains/todo/aggregate.go b/examples/todomvc/backend/domains/todo/aggregate.go
index e97a840..ebbb6f8 100644
--- a/examples/todomvc/backend/domains/todo/aggregate.go
+++ b/examples/todomvc/backend/domains/todo/aggregate.go
@@ -20,9 +20,9 @@ import (
 	"fmt"
 	"time"
 
-	"github.com/google/uuid"
 	eh "github.com/looplab/eventhorizon"
 	"github.com/looplab/eventhorizon/aggregatestore/events"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 func init() {
diff --git a/examples/todomvc/backend/domains/todo/commands.go b/examples/todomvc/backend/domains/todo/commands.go
index e1c5bde..8effb31 100644
--- a/examples/todomvc/backend/domains/todo/commands.go
+++ b/examples/todomvc/backend/domains/todo/commands.go
@@ -15,8 +15,8 @@
 package todo
 
 import (
-	"github.com/google/uuid"
 	eh "github.com/looplab/eventhorizon"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 func init() {
diff --git a/examples/todomvc/backend/domains/todo/model.go b/examples/todomvc/backend/domains/todo/model.go
index 201309b..8179c64 100644
--- a/examples/todomvc/backend/domains/todo/model.go
+++ b/examples/todomvc/backend/domains/todo/model.go
@@ -17,8 +17,8 @@ package todo
 import (
 	"time"
 
-	"github.com/google/uuid"
 	eh "github.com/looplab/eventhorizon"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 // TodoItem represents each item that can be completed in the todo list.
diff --git a/examples/todomvc/backend/main.go b/examples/todomvc/backend/main.go
index 22fdc02..0d19efc 100644
--- a/examples/todomvc/backend/main.go
+++ b/examples/todomvc/backend/main.go
@@ -21,8 +21,6 @@ import (
 	"os"
 	"os/signal"
 
-	"github.com/google/uuid"
-
 	eh "github.com/looplab/eventhorizon"
 	"github.com/looplab/eventhorizon/commandhandler/bus"
 	gcpEventBus "github.com/looplab/eventhorizon/eventbus/gcp"
@@ -34,6 +32,7 @@ import (
 	mongoRepo "github.com/looplab/eventhorizon/repo/mongodb"
 	tracingRepo "github.com/looplab/eventhorizon/repo/tracing"
 	"github.com/looplab/eventhorizon/repo/version"
+	"github.com/looplab/eventhorizon/uuid"
 
 	"github.com/looplab/eventhorizon/examples/todomvc/backend/domains/todo"
 	"github.com/looplab/eventhorizon/examples/todomvc/backend/handler"
diff --git a/httputils/query.go b/httputils/query.go
index 4712d8a..f22ae31 100644
--- a/httputils/query.go
+++ b/httputils/query.go
@@ -20,8 +20,8 @@ import (
 	"net/http"
 	"path"
 
-	"github.com/google/uuid"
 	eh "github.com/looplab/eventhorizon"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 // QueryHandler returns one or all items from a eventhorizon.ReadRepo. If the
diff --git a/middleware/eventhandler/observer/middleware.go b/middleware/eventhandler/observer/middleware.go
index 6d8a8fe..a20ee9e 100644
--- a/middleware/eventhandler/observer/middleware.go
+++ b/middleware/eventhandler/observer/middleware.go
@@ -18,8 +18,8 @@ import (
 	"fmt"
 	"os"
 
-	"github.com/google/uuid"
 	eh "github.com/looplab/eventhorizon"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 // Group provides groupings of observers by different criteria.
diff --git a/mocks/mocks.go b/mocks/mocks.go
index f9a9d45..5b32373 100644
--- a/mocks/mocks.go
+++ b/mocks/mocks.go
@@ -19,8 +19,8 @@ import (
 	"sync"
 	"time"
 
-	"github.com/google/uuid"
 	eh "github.com/looplab/eventhorizon"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 func init() {
diff --git a/repo.go b/repo.go
index 14db7e4..340978c 100644
--- a/repo.go
+++ b/repo.go
@@ -18,7 +18,7 @@ import (
 	"context"
 	"errors"
 
-	"github.com/google/uuid"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 // ReadRepo is a read repository for entities.
diff --git a/repo/cache/repo.go b/repo/cache/repo.go
index 339b1c1..5d45067 100644
--- a/repo/cache/repo.go
+++ b/repo/cache/repo.go
@@ -19,8 +19,8 @@ import (
 	"fmt"
 	"sync"
 
-	"github.com/google/uuid"
 	eh "github.com/looplab/eventhorizon"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 type namespace string
diff --git a/repo/memory/repo.go b/repo/memory/repo.go
index 1251b40..881a8d0 100644
--- a/repo/memory/repo.go
+++ b/repo/memory/repo.go
@@ -20,9 +20,8 @@ import (
 	"errors"
 	"sync"
 
-	"github.com/google/uuid"
-
 	eh "github.com/looplab/eventhorizon"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 type namespace string
diff --git a/repo/mongodb/repo.go b/repo/mongodb/repo.go
index 84e231b..a3f62aa 100644
--- a/repo/mongodb/repo.go
+++ b/repo/mongodb/repo.go
@@ -19,7 +19,6 @@ import (
 	"errors"
 	"fmt"
 
-	"github.com/google/uuid"
 	"go.mongodb.org/mongo-driver/bson"
 	"go.mongodb.org/mongo-driver/mongo"
 	"go.mongodb.org/mongo-driver/mongo/options"
@@ -32,6 +31,7 @@ import (
 	_ "github.com/looplab/eventhorizon/codec/bson"
 
 	eh "github.com/looplab/eventhorizon"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 var (
diff --git a/repo/tracing/repo.go b/repo/tracing/repo.go
index 6229284..7cd3553 100644
--- a/repo/tracing/repo.go
+++ b/repo/tracing/repo.go
@@ -17,10 +17,11 @@ package tracing
 import (
 	"context"
 
-	"github.com/google/uuid"
-	eh "github.com/looplab/eventhorizon"
 	"github.com/opentracing/opentracing-go"
 	"github.com/opentracing/opentracing-go/ext"
+
+	eh "github.com/looplab/eventhorizon"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 // Repo is a ReadWriteRepo that adds tracing.
diff --git a/repo/version/repo.go b/repo/version/repo.go
index 7384da8..8d3b834 100644
--- a/repo/version/repo.go
+++ b/repo/version/repo.go
@@ -18,9 +18,10 @@ import (
 	"context"
 	"time"
 
-	"github.com/google/uuid"
 	"github.com/jpillora/backoff"
+
 	eh "github.com/looplab/eventhorizon"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 // Repo is a middleware that adds version checking to a read repository.
diff --git a/uuid/uuid.go b/uuid/uuid.go
new file mode 100644
index 0000000..0e204db
--- /dev/null
+++ b/uuid/uuid.go
@@ -0,0 +1,27 @@
+// Package UUID provides an easy to replace UUID package.
+// Forks of Event Horizon can re-implement this package with a UUID library of choice.
+package uuid
+
+import "github.com/google/uuid"
+
+// UUID is an alias type for github.com/google/uuid.UUID
+type UUID = uuid.UUID
+
+// Nil is an empty UUID.
+var Nil = UUID(uuid.Nil)
+
+// New creates a new UUID.
+func New() UUID {
+	return UUID(uuid.New())
+}
+
+// Parse parses a UUID from a string, or returns an error.
+func Parse(s string) (UUID, error) {
+	id, err := uuid.Parse(s)
+	return UUID(id), err
+}
+
+// MustParse parses a UUID from a string, or panics.
+func MustParse(s string) UUID {
+	return UUID(uuid.MustParse(s))
+}


Test patch:
diff --git a/aggregate_test.go b/aggregate_test.go
index e047125..0c50260 100644
--- a/aggregate_test.go
+++ b/aggregate_test.go
@@ -19,7 +19,7 @@ import (
 	"errors"
 	"testing"
 
-	"github.com/google/uuid"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 func TestCreateAggregate(t *testing.T) {
diff --git a/aggregatestore/events/aggregatebase.go b/aggregatestore/events/aggregatebase.go
index 7eacba5..08b8e5f 100644
--- a/aggregatestore/events/aggregatebase.go
+++ b/aggregatestore/events/aggregatebase.go
@@ -17,8 +17,8 @@ package events
 import (
 	"time"
 
-	"github.com/google/uuid"
 	eh "github.com/looplab/eventhorizon"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 // AggregateBase is a event sourced aggregate base to embed in a domain aggregate.
diff --git a/aggregatestore/events/aggregatebase_test.go b/aggregatestore/events/aggregatebase_test.go
index 14931b5..1868ffb 100644
--- a/aggregatestore/events/aggregatebase_test.go
+++ b/aggregatestore/events/aggregatebase_test.go
@@ -20,8 +20,8 @@ import (
 	"testing"
 	"time"
 
-	"github.com/google/uuid"
 	eh "github.com/looplab/eventhorizon"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 func TestNewAggregateBase(t *testing.T) {
diff --git a/aggregatestore/events/aggregatestore.go b/aggregatestore/events/aggregatestore.go
index af4f63f..4b4ce77 100644
--- a/aggregatestore/events/aggregatestore.go
+++ b/aggregatestore/events/aggregatestore.go
@@ -18,8 +18,8 @@ import (
 	"context"
 	"errors"
 
-	"github.com/google/uuid"
 	eh "github.com/looplab/eventhorizon"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 // AggregateStore is an aggregate store using event sourcing. It
diff --git a/aggregatestore/events/aggregatestore_test.go b/aggregatestore/events/aggregatestore_test.go
index b599251..13418f4 100644
--- a/aggregatestore/events/aggregatestore_test.go
+++ b/aggregatestore/events/aggregatestore_test.go
@@ -21,9 +21,9 @@ import (
 	"testing"
 	"time"
 
-	"github.com/google/uuid"
 	eh "github.com/looplab/eventhorizon"
 	"github.com/looplab/eventhorizon/mocks"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 func TestNewAggregateStore(t *testing.T) {
diff --git a/aggregatestore/model/aggregatestore.go b/aggregatestore/model/aggregatestore.go
index 45ba0ef..0ecbbe7 100644
--- a/aggregatestore/model/aggregatestore.go
+++ b/aggregatestore/model/aggregatestore.go
@@ -18,8 +18,8 @@ import (
 	"context"
 	"errors"
 
-	"github.com/google/uuid"
 	eh "github.com/looplab/eventhorizon"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 // AggregateStore is an aggregate store that uses a read write repo for
diff --git a/aggregatestore/model/aggregatestore_test.go b/aggregatestore/model/aggregatestore_test.go
index 0eee938..b2eeb55 100644
--- a/aggregatestore/model/aggregatestore_test.go
+++ b/aggregatestore/model/aggregatestore_test.go
@@ -21,9 +21,9 @@ import (
 	"testing"
 	"time"
 
-	"github.com/google/uuid"
 	eh "github.com/looplab/eventhorizon"
 	"github.com/looplab/eventhorizon/mocks"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 func TestNewAggregateStore(t *testing.T) {
diff --git a/codec/acceptance_testing.go b/codec/acceptance_testing.go
index 22aaf7d..14c85db 100644
--- a/codec/acceptance_testing.go
+++ b/codec/acceptance_testing.go
@@ -19,10 +19,9 @@ import (
 	"testing"
 	"time"
 
-	"github.com/google/uuid"
-
 	eh "github.com/looplab/eventhorizon"
 	"github.com/looplab/eventhorizon/mocks"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 func init() {
diff --git a/command_test.go b/command_test.go
index 01a9166..66f9081 100644
--- a/command_test.go
+++ b/command_test.go
@@ -19,7 +19,7 @@ import (
 	"testing"
 	"time"
 
-	"github.com/google/uuid"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 func TestCreateCommand(t *testing.T) {
diff --git a/commandhandler/aggregate/commandhandler_test.go b/commandhandler/aggregate/commandhandler_test.go
index 2e7dbcc..dccf919 100644
--- a/commandhandler/aggregate/commandhandler_test.go
+++ b/commandhandler/aggregate/commandhandler_test.go
@@ -20,9 +20,9 @@ import (
 	"reflect"
 	"testing"
 
-	"github.com/google/uuid"
 	eh "github.com/looplab/eventhorizon"
 	"github.com/looplab/eventhorizon/mocks"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 func TestNewCommandHandler(t *testing.T) {
diff --git a/commandhandler/bus/commandhandler_test.go b/commandhandler/bus/commandhandler_test.go
index 8e374f6..62b5a90 100644
--- a/commandhandler/bus/commandhandler_test.go
+++ b/commandhandler/bus/commandhandler_test.go
@@ -20,9 +20,9 @@ import (
 	"reflect"
 	"testing"
 
-	"github.com/google/uuid"
 	eh "github.com/looplab/eventhorizon"
 	"github.com/looplab/eventhorizon/mocks"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 func TestCommandHandler(t *testing.T) {
diff --git a/event_test.go b/event_test.go
index 494d55a..c1b8a3a 100644
--- a/event_test.go
+++ b/event_test.go
@@ -20,7 +20,7 @@ import (
 	"testing"
 	"time"
 
-	"github.com/google/uuid"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 func TestNewEvent(t *testing.T) {
diff --git a/eventbus/acceptance_testing.go b/eventbus/acceptance_testing.go
index 09d279e..77b5173 100644
--- a/eventbus/acceptance_testing.go
+++ b/eventbus/acceptance_testing.go
@@ -22,12 +22,12 @@ import (
 	"testing"
 	"time"
 
-	"github.com/google/uuid"
 	"github.com/kr/pretty"
 
 	eh "github.com/looplab/eventhorizon"
 	"github.com/looplab/eventhorizon/middleware/eventhandler/observer"
 	"github.com/looplab/eventhorizon/mocks"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 // AcceptanceTest is the acceptance test that all implementations of EventBus
diff --git a/eventhandler/projector/eventhandler_test.go b/eventhandler/projector/eventhandler_test.go
index 4bbaf82..1533c84 100644
--- a/eventhandler/projector/eventhandler_test.go
+++ b/eventhandler/projector/eventhandler_test.go
@@ -21,10 +21,10 @@ import (
 	"testing"
 	"time"
 
-	"github.com/google/uuid"
 	eh "github.com/looplab/eventhorizon"
 	"github.com/looplab/eventhorizon/mocks"
 	"github.com/looplab/eventhorizon/repo/version"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 func TestEventHandler_CreateModel(t *testing.T) {
diff --git a/eventhandler/saga/eventhandler_test.go b/eventhandler/saga/eventhandler_test.go
index f4deff4..60514ae 100644
--- a/eventhandler/saga/eventhandler_test.go
+++ b/eventhandler/saga/eventhandler_test.go
@@ -20,9 +20,9 @@ import (
 	"testing"
 	"time"
 
-	"github.com/google/uuid"
 	eh "github.com/looplab/eventhorizon"
 	"github.com/looplab/eventhorizon/mocks"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 func TestEventHandler(t *testing.T) {
diff --git a/eventhandler/waiter/eventhandler_test.go b/eventhandler/waiter/eventhandler_test.go
index 9077706..c6b3f9e 100644
--- a/eventhandler/waiter/eventhandler_test.go
+++ b/eventhandler/waiter/eventhandler_test.go
@@ -22,9 +22,9 @@ import (
 
 	"time"
 
-	"github.com/google/uuid"
 	eh "github.com/looplab/eventhorizon"
 	"github.com/looplab/eventhorizon/mocks"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 func TestEventHandler(t *testing.T) {
diff --git a/eventstore/acceptanece_testing.go b/eventstore/acceptanece_testing.go
index 6a33d50..1f9f27b 100644
--- a/eventstore/acceptanece_testing.go
+++ b/eventstore/acceptanece_testing.go
@@ -21,10 +21,9 @@ import (
 	"testing"
 	"time"
 
-	"github.com/google/uuid"
-
 	eh "github.com/looplab/eventhorizon"
 	"github.com/looplab/eventhorizon/mocks"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 // AcceptanceTest is the acceptance test that all implementations of EventStore
diff --git a/eventstore/maintenance_testing.go b/eventstore/maintenance_testing.go
index 008584c..01d7c31 100644
--- a/eventstore/maintenance_testing.go
+++ b/eventstore/maintenance_testing.go
@@ -19,10 +19,9 @@ import (
 	"testing"
 	"time"
 
-	"github.com/google/uuid"
-
 	eh "github.com/looplab/eventhorizon"
 	"github.com/looplab/eventhorizon/mocks"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 // MaintenanceAcceptanceTest is the acceptance test that all implementations of
diff --git a/eventstore/memory/eventstore_test.go b/eventstore/memory/eventstore_test.go
index dace9c4..488a1d2 100644
--- a/eventstore/memory/eventstore_test.go
+++ b/eventstore/memory/eventstore_test.go
@@ -19,10 +19,10 @@ import (
 	"testing"
 	"time"
 
-	"github.com/google/uuid"
 	eh "github.com/looplab/eventhorizon"
 	"github.com/looplab/eventhorizon/eventstore"
 	"github.com/looplab/eventhorizon/mocks"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 func TestEventStore(t *testing.T) {
diff --git a/eventstore/mongodb/eventstore_test.go b/eventstore/mongodb/eventstore_test.go
index fb590aa..0369290 100644
--- a/eventstore/mongodb/eventstore_test.go
+++ b/eventstore/mongodb/eventstore_test.go
@@ -22,11 +22,10 @@ import (
 	"testing"
 	"time"
 
-	"github.com/google/uuid"
-
 	eh "github.com/looplab/eventhorizon"
 	"github.com/looplab/eventhorizon/eventstore"
 	"github.com/looplab/eventhorizon/mocks"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 func TestEventStoreIntegration(t *testing.T) {
diff --git a/examples/guestlist/memory/memory_test.go b/examples/guestlist/memory/memory_test.go
index 9531eba..75aab74 100644
--- a/examples/guestlist/memory/memory_test.go
+++ b/examples/guestlist/memory/memory_test.go
@@ -22,13 +22,14 @@ import (
 	"sync"
 	"time"
 
-	"github.com/google/uuid"
 	eh "github.com/looplab/eventhorizon"
 	"github.com/looplab/eventhorizon/commandhandler/bus"
 	localEventBus "github.com/looplab/eventhorizon/eventbus/local"
 	memoryEventStore "github.com/looplab/eventhorizon/eventstore/memory"
-	"github.com/looplab/eventhorizon/examples/guestlist/domains/guestlist"
 	"github.com/looplab/eventhorizon/repo/memory"
+	"github.com/looplab/eventhorizon/uuid"
+
+	"github.com/looplab/eventhorizon/examples/guestlist/domains/guestlist"
 )
 
 // NOTE: Not named "Integration" to enable running with the unit tests.
diff --git a/examples/guestlist/mongodb/mongodb_test.go b/examples/guestlist/mongodb/mongodb_test.go
index 55d488d..d766f1d 100644
--- a/examples/guestlist/mongodb/mongodb_test.go
+++ b/examples/guestlist/mongodb/mongodb_test.go
@@ -24,14 +24,13 @@ import (
 	"testing"
 	"time"
 
-	"github.com/google/uuid"
-
 	eh "github.com/looplab/eventhorizon"
 	"github.com/looplab/eventhorizon/commandhandler/bus"
 	localEventBus "github.com/looplab/eventhorizon/eventbus/local"
 	mongoEventStore "github.com/looplab/eventhorizon/eventstore/mongodb"
 	"github.com/looplab/eventhorizon/repo/mongodb"
 	"github.com/looplab/eventhorizon/repo/version"
+	"github.com/looplab/eventhorizon/uuid"
 
 	"github.com/looplab/eventhorizon/examples/guestlist/domains/guestlist"
 )
diff --git a/examples/todomvc/backend/domains/todo/aggregate_test.go b/examples/todomvc/backend/domains/todo/aggregate_test.go
index d402ed3..51fb1b9 100644
--- a/examples/todomvc/backend/domains/todo/aggregate_test.go
+++ b/examples/todomvc/backend/domains/todo/aggregate_test.go
@@ -21,11 +21,12 @@ import (
 	"testing"
 	"time"
 
-	"github.com/google/uuid"
 	"github.com/kr/pretty"
+
 	eh "github.com/looplab/eventhorizon"
 	"github.com/looplab/eventhorizon/aggregatestore/events"
 	"github.com/looplab/eventhorizon/mocks"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 func TestAggregateHandleCommand(t *testing.T) {
diff --git a/examples/todomvc/backend/domains/todo/model_test.go b/examples/todomvc/backend/domains/todo/model_test.go
index 7c2bff9..9baf42e 100644
--- a/examples/todomvc/backend/domains/todo/model_test.go
+++ b/examples/todomvc/backend/domains/todo/model_test.go
@@ -20,7 +20,7 @@ import (
 	"testing"
 	"time"
 
-	"github.com/google/uuid"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 func TestModelJSON(t *testing.T) {
diff --git a/examples/todomvc/backend/domains/todo/projector_test.go b/examples/todomvc/backend/domains/todo/projector_test.go
index d1bfcda..b79964c 100644
--- a/examples/todomvc/backend/domains/todo/projector_test.go
+++ b/examples/todomvc/backend/domains/todo/projector_test.go
@@ -21,9 +21,10 @@ import (
 	"testing"
 	"time"
 
-	"github.com/google/uuid"
 	"github.com/kr/pretty"
+
 	eh "github.com/looplab/eventhorizon"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 func TestProjector(t *testing.T) {
diff --git a/examples/todomvc/backend/handler/handler_test.go b/examples/todomvc/backend/handler/handler_test.go
index 24294c0..f523c15 100644
--- a/examples/todomvc/backend/handler/handler_test.go
+++ b/examples/todomvc/backend/handler/handler_test.go
@@ -26,8 +26,6 @@ import (
 	"testing"
 	"time"
 
-	"github.com/google/uuid"
-
 	eh "github.com/looplab/eventhorizon"
 	"github.com/looplab/eventhorizon/commandhandler/bus"
 	gcpEventBus "github.com/looplab/eventhorizon/eventbus/gcp"
@@ -39,6 +37,7 @@ import (
 	"github.com/looplab/eventhorizon/repo/memory"
 	"github.com/looplab/eventhorizon/repo/mongodb"
 	"github.com/looplab/eventhorizon/repo/version"
+	"github.com/looplab/eventhorizon/uuid"
 
 	"github.com/looplab/eventhorizon/examples/todomvc/backend/domains/todo"
 )
diff --git a/matcher_test.go b/matcher_test.go
index f217484..a35eb3a 100644
--- a/matcher_test.go
+++ b/matcher_test.go
@@ -18,7 +18,7 @@ import (
 	"testing"
 	"time"
 
-	"github.com/google/uuid"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 func TestMatchEvents(t *testing.T) {
diff --git a/middleware/commandhandler/async/middleware_test.go b/middleware/commandhandler/async/middleware_test.go
index f2023e1..35a94cc 100644
--- a/middleware/commandhandler/async/middleware_test.go
+++ b/middleware/commandhandler/async/middleware_test.go
@@ -21,9 +21,9 @@ import (
 	"testing"
 	"time"
 
-	"github.com/google/uuid"
 	eh "github.com/looplab/eventhorizon"
 	"github.com/looplab/eventhorizon/mocks"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 func TestCommandHandler(t *testing.T) {
diff --git a/middleware/commandhandler/scheduler/middleware_test.go b/middleware/commandhandler/scheduler/middleware_test.go
index 58626f2..5e90c65 100644
--- a/middleware/commandhandler/scheduler/middleware_test.go
+++ b/middleware/commandhandler/scheduler/middleware_test.go
@@ -21,9 +21,9 @@ import (
 	"testing"
 	"time"
 
-	"github.com/google/uuid"
 	eh "github.com/looplab/eventhorizon"
 	"github.com/looplab/eventhorizon/mocks"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 func TestCommandHandler_Immediate(t *testing.T) {
diff --git a/middleware/commandhandler/validator/middleware_test.go b/middleware/commandhandler/validator/middleware_test.go
index f7aa1a8..97681d4 100644
--- a/middleware/commandhandler/validator/middleware_test.go
+++ b/middleware/commandhandler/validator/middleware_test.go
@@ -20,9 +20,9 @@ import (
 	"reflect"
 	"testing"
 
-	"github.com/google/uuid"
 	eh "github.com/looplab/eventhorizon"
 	"github.com/looplab/eventhorizon/mocks"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 func TestCommandHandler_Immediate(t *testing.T) {
diff --git a/middleware/eventhandler/async/middleware_test.go b/middleware/eventhandler/async/middleware_test.go
index ffc09ba..827290f 100644
--- a/middleware/eventhandler/async/middleware_test.go
+++ b/middleware/eventhandler/async/middleware_test.go
@@ -21,9 +21,9 @@ import (
 	"testing"
 	"time"
 
-	"github.com/google/uuid"
 	eh "github.com/looplab/eventhorizon"
 	"github.com/looplab/eventhorizon/mocks"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 func TestEventHandler(t *testing.T) {
diff --git a/middleware/eventhandler/observer/middleware_test.go b/middleware/eventhandler/observer/middleware_test.go
index b4dffbb..103d43d 100644
--- a/middleware/eventhandler/observer/middleware_test.go
+++ b/middleware/eventhandler/observer/middleware_test.go
@@ -20,9 +20,9 @@ import (
 	"testing"
 	"time"
 
-	"github.com/google/uuid"
 	eh "github.com/looplab/eventhorizon"
 	"github.com/looplab/eventhorizon/mocks"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 func TestEventHandler(t *testing.T) {
diff --git a/middleware/eventhandler/scheduler/middleware_test.go b/middleware/eventhandler/scheduler/middleware_test.go
index 7ef6c91..da48b55 100644
--- a/middleware/eventhandler/scheduler/middleware_test.go
+++ b/middleware/eventhandler/scheduler/middleware_test.go
@@ -21,9 +21,9 @@ import (
 	"testing"
 	"time"
 
-	"github.com/google/uuid"
 	eh "github.com/looplab/eventhorizon"
 	"github.com/looplab/eventhorizon/mocks"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 func TestCommandHandler(t *testing.T) {
diff --git a/middleware_test.go b/middleware_test.go
index 624b8cc..273ff6d 100644
--- a/middleware_test.go
+++ b/middleware_test.go
@@ -20,7 +20,7 @@ import (
 	"testing"
 	"time"
 
-	"github.com/google/uuid"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 func TestCommandHandlerMiddleware(t *testing.T) {
diff --git a/repo/acceptance_testing.go b/repo/acceptance_testing.go
index ce5d310..90d3066 100644
--- a/repo/acceptance_testing.go
+++ b/repo/acceptance_testing.go
@@ -20,9 +20,9 @@ import (
 	"testing"
 	"time"
 
-	"github.com/google/uuid"
 	eh "github.com/looplab/eventhorizon"
 	"github.com/looplab/eventhorizon/mocks"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 // AcceptanceTest is the acceptance test that all implementations of Repo
diff --git a/repo/mongodb/repo_test.go b/repo/mongodb/repo_test.go
index 901bc5b..5896ed8 100644
--- a/repo/mongodb/repo_test.go
+++ b/repo/mongodb/repo_test.go
@@ -24,13 +24,13 @@ import (
 	"testing"
 	"time"
 
-	"github.com/google/uuid"
 	"go.mongodb.org/mongo-driver/bson"
 	"go.mongodb.org/mongo-driver/mongo"
 
 	eh "github.com/looplab/eventhorizon"
 	"github.com/looplab/eventhorizon/mocks"
 	"github.com/looplab/eventhorizon/repo"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 func TestReadRepoIntegration(t *testing.T) {
diff --git a/repo/version/repo_test.go b/repo/version/repo_test.go
index a146a7d..769560b 100644
--- a/repo/version/repo_test.go
+++ b/repo/version/repo_test.go
@@ -21,11 +21,11 @@ import (
 	"testing"
 	"time"
 
-	"github.com/google/uuid"
 	eh "github.com/looplab/eventhorizon"
 	"github.com/looplab/eventhorizon/mocks"
 	"github.com/looplab/eventhorizon/repo"
 	"github.com/looplab/eventhorizon/repo/memory"
+	"github.com/looplab/eventhorizon/uuid"
 )
 
 // NOTE: Not named "Integration" to enable running with the unit tests.