Skip to content

Commit

Permalink
angepasstes Readmodel aus Eventsourcing
Browse files Browse the repository at this point in the history
  • Loading branch information
CarstenKoenig committed Oct 20, 2014
1 parent 138591a commit 2c707eb
Show file tree
Hide file tree
Showing 10 changed files with 87 additions and 159 deletions.
3 changes: 3 additions & 0 deletions GrauhundReisen.DomainFunktional/Booking.fs
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,9 @@ module Booking =
let registerEventHandler handler (Service service) =
service |> EventStore.subscribe handler

let registerReadmodel rm (Service service) =
EventStore.registerReadmodel service rm

let order (bookingId, destination, creditCard, email, name) (Service service) =
let event =
create bookingId name email creditCard destination
Expand Down
1 change: 0 additions & 1 deletion GrauhundReisen.ReadModel/GrauhundReisen.ReadModel.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
<Compile Include="Models\CreditCardType.cs" />
<Compile Include="Models\Destination.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Repositories\Bookings.cs" />
<Compile Include="Repositories\CreditCardTypes.cs" />
<Compile Include="Repositories\Destinations.cs" />
<Compile Include="Repositories\BookingForm.cs" />
Expand Down
69 changes: 0 additions & 69 deletions GrauhundReisen.ReadModel/Repositories/Bookings.cs

This file was deleted.

83 changes: 21 additions & 62 deletions GrauhundReisen.ReadModelFunktional/Booking.fs
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,7 @@ module Booking =
Id : string
}

let empty =
{ CreditCardNumber = ""
CreditCardType = ""
Destination = ""
EMail = ""
FirstName = ""
LastName = ""
Id = string GrauhundReisen.DomainFunktional.Booking.BookingId.Empty
}

let create (id, first, last, email, credType, credNr, dest) =
let internal create (id, first, last, email, credType, credNr, dest) =
{ CreditCardNumber = credNr
CreditCardType = credType
Destination = dest
Expand All @@ -35,54 +25,23 @@ module Booking =
Id = id
}

let none : T option = None

let some t : T option = Some t

type IRepository =
abstract GetBy : Id -> T option
abstract Delete : Id -> unit
abstract Save : T -> unit

module Projections =
open EventSourcing.Projection
open GrauhundReisen.DomainFunktional.Booking
open GrauhundReisen.DomainFunktional.Booking.Projections

let booking =
EventSourcing.Projection.create
empty
(fun b ev ->
match ev with
| Events.Ordered (GrauhundReisen.DomainFunktional.Booking.Booking (id, order)) ->
let (ct,cn) = GrauhundReisen.DomainFunktional.Booking.Convert.fromCreditCard order.CreditCard
let (GrauhundReisen.DomainFunktional.Booking.Email email) = order.Email
{ b with Id = string id
CreditCardType = ct
CreditCardNumber = cn
Destination = order.Destination
EMail = email
FirstName = order.Name.Givenname
LastName = order.Name.Surname
}
| Events.EmailChanged (GrauhundReisen.DomainFunktional.Booking.Email email) ->
{ b with EMail = email }
| Events.CreditCardChanged creditCard ->
let (ct,cn) = GrauhundReisen.DomainFunktional.Booking.Convert.fromCreditCard creditCard
{ b with CreditCardType = ct
CreditCardNumber = cn
})

let eventHandler (repo : IRepository)
(id : GrauhundReisen.DomainFunktional.Booking.BookingId, event : Events) =
let readModelFrom =
match repo.GetBy (id.ToString()) with
| Some rm -> rm
| None -> empty
// das gefällt mir so noch nicht - das ist die Schwäche des "Zwischenschritts/Typs"
let readModelTo = EventSourcing.Projection.foldFrom Projections.booking readModelFrom (Seq.singleton event)
repo.Delete (id.ToString())
repo.Save readModelTo

let RegisterAt(repo : IRepository, service : GrauhundReisen.DomainFunktional.Booking.Service.T) =
service |> GrauhundReisen.DomainFunktional.Booking.Service.registerEventHandler (eventHandler repo)
type ReadModel internal (load) =
member __.Load(key) = load key

let createFileIO path =
let proj =
GrauhundReisen.DomainFunktional.Booking.Projections.booking
|> EventSourcing.Projection.map
(fun (GrauhundReisen.DomainFunktional.Booking.Booking (id,order)) ->
let (GrauhundReisen.DomainFunktional.Booking.Email email) = order.Email
let (ct, cn) = GrauhundReisen.DomainFunktional.Booking.Convert.fromCreditCard order.CreditCard
create (string id, order.Name.Givenname, order.Name.Surname, email, ct, cn, order.Destination))
EventSourcing.ReadModel.create
(FileKeyValueStore.createFileStore path)
proj
(fun id _ -> id)

let createReadModel path =
let rm = createFileIO path
ReadModel (fun key ->
EventSourcing.ReadModel.load rm (EventSourcing.EntityId.Parse key))
27 changes: 27 additions & 0 deletions GrauhundReisen.ReadModelFunktional/FileKeyValueStore.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
namespace GrauhundReisen.ReadModelFunktional

open EventSourcing
open System.IO
open Newtonsoft.Json

module FileKeyValueStore =

let createFileStore<'key,'value> (path : string) : IKeyValueStore<'key,'value> =
let readFromFile key =
try
let path = Path.Combine (path, key.ToString())
if not <| File.Exists path then None else
let content = File.ReadAllText path
JsonConvert.DeserializeObject<'value> content
|> Some
with
| _ -> None
let writeToFile (key, value) =
let path = Path.Combine(path, key.ToString())
let json = JsonConvert.SerializeObject value
if File.Exists path then File.Delete path else
File.WriteAllText(path, json)
{ new IKeyValueStore<'key,'value> with
member __.Read key = readFromFile key
member __.Save key value = writeToFile (key, value)
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,27 @@
<WarningLevel>3</WarningLevel>
<DocumentationFile>bin\Release\GrauhundReisen.ReadModelFunktional.XML</DocumentationFile>
</PropertyGroup>
<PropertyGroup>
<MinimumVisualStudioVersion Condition="'$(MinimumVisualStudioVersion)' == ''">11</MinimumVisualStudioVersion>
</PropertyGroup>
<Choose>
<When Condition="'$(VisualStudioVersion)' == '11.0'">
<PropertyGroup Condition="Exists('$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets')">
<FSharpTargetsPath>$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets</FSharpTargetsPath>
</PropertyGroup>
</When>
<Otherwise>
<PropertyGroup Condition="Exists('$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets')">
<FSharpTargetsPath>$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets</FSharpTargetsPath>
</PropertyGroup>
</Otherwise>
</Choose>
<Import Project="$(FSharpTargetsPath)" />
<ItemGroup>
<Compile Include="FileKeyValueStore.fs" />
<Compile Include="Booking.fs" />
<Content Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Reference Include="EventSourcing">
<HintPath>..\packages\EventSourcing.dll</HintPath>
Expand All @@ -40,36 +61,19 @@
<Reference Include="FSharp.Core, Version=$(TargetFSharpCoreVersion), Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<Private>True</Private>
</Reference>
<Reference Include="Newtonsoft.Json">
<HintPath>..\packages\Newtonsoft.Json.6.0.5\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Numerics" />
</ItemGroup>
<ItemGroup>
<Compile Include="Booking.fs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\GrauhundReisen.DomainFunktional\GrauhundReisen.DomainFunktional.fsproj">
<Name>GrauhundReisen.DomainFunktional</Name>
<Project>{a7f6157d-cb71-4c47-baac-f50a810690e5}</Project>
<Private>True</Private>
</ProjectReference>
</ItemGroup>
<PropertyGroup>
<MinimumVisualStudioVersion Condition="'$(MinimumVisualStudioVersion)' == ''">11</MinimumVisualStudioVersion>
</PropertyGroup>
<Choose>
<When Condition="'$(VisualStudioVersion)' == '11.0'">
<PropertyGroup Condition="Exists('$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets')">
<FSharpTargetsPath>$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets</FSharpTargetsPath>
</PropertyGroup>
</When>
<Otherwise>
<PropertyGroup Condition="Exists('$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets')">
<FSharpTargetsPath>$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets</FSharpTargetsPath>
</PropertyGroup>
</Otherwise>
</Choose>
<Import Project="$(FSharpTargetsPath)" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
Expand Down
4 changes: 4 additions & 0 deletions GrauhundReisen.ReadModelFunktional/packages.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Newtonsoft.Json" version="6.0.5" targetFramework="net45" />
</packages>
6 changes: 3 additions & 3 deletions GrauhundReisen.WebPortal/Boostrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,15 @@ protected override void ApplicationStartup(TinyIoCContainer container, Nancy.Boo

private static void SetupIoC(TinyIoCContainer container)
{
var bookingReadmodelRepo = new Bookings (ConnectionString);
var repostiory = EventSourcing.Repositories.InMemory.create(false);
var bookingService = DomainFunktional.Booking.Service.fromRepository(repostiory);

ReadModelFunktional.Booking.RegisterAt (bookingReadmodelRepo, bookingService);
var readModel = ReadModelFunktional.Booking.createReadModel(ConnectionString);
DomainFunktional.Booking.Service.registerReadmodel(ReadModelFunktional.Booking.createFileIO(ConnectionString), bookingService);

container.Register(bookingService);
container.Register<BookingForm>();
container.Register(bookingReadmodelRepo);
container.Register(readModel);
}
}
}
6 changes: 3 additions & 3 deletions GrauhundReisen.WebPortal/Controller/Booking.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ namespace GrauhundReisen.WebPortal
{
public class Booking : NancyModule
{
readonly Bookings _bookings;
readonly ReadModelFunktional.Booking.ReadModel _bookings;
readonly DomainFunktional.Booking.Service.T _bookingService;

public Booking(Bookings bookings, DomainFunktional.Booking.Service.T bookingService)
public Booking(ReadModelFunktional.Booking.ReadModel bookings, DomainFunktional.Booking.Service.T bookingService)
{
_bookings = bookings;
_bookingService = bookingService;
Expand All @@ -23,7 +23,7 @@ public Booking(Bookings bookings, DomainFunktional.Booking.Service.T bookingServ
object GetBookingFormFor (string bookingId)
{

var booking = _bookings.GetBookingBy (bookingId);
var booking = _bookings.Load(bookingId);

return View ["change-booking", booking];
}
Expand Down
1 change: 1 addition & 0 deletions GrauhundReisen.WebPortal/GrauhundReisen.WebPortal.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\EventSourcing.dll</HintPath>
</Reference>
<Reference Include="FSharp.Core, Version=4.3.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
<Reference Include="System" />
<Reference Include="System.Web" />
<Reference Include="System.Xml" />
Expand Down

0 comments on commit 2c707eb

Please sign in to comment.