Giter Site home page Giter Site logo

fsuno's People

Contributors

thinkbeforecoding avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fsuno's Issues

Aggregate ids should not be baked into Events/Commands

I know this is just a demo and could remove some intentional complexity which you are using for pedagogical purposes but...

In my experience, the id is best left ouside of the aggregate itself, unless there is a good reason (much like the version). This would remove the need for a gameId function.

I believe removing it would also make the example clearer, as the 1s look likes magic numbers (and aggregate ids in both NES and GES can be strings which can be uses/abused for lots of things)

The primary con is that it raises the need for 'event dispatch' and 'command handling' to pass it (and for any publishing to separately pass it, which brings notions of enrichement into the picture (all depends on your point of view whether that's good or bad)

(Also I see a Discard Pile seems to be an accepted Domain Term in Cards in general but refers more to the side effect than the ongoing game. Thus I believe I'd actually use UnoGame as the name for your aggregate. (And I think I would take the AutoOpen off the Aggregate module but leave it on the Commands and Events (which should be namespaces not modules?)) and let the UnoGame. flow all the way out into the tests:-

open FsUno 
open FsUno.UnoGame.Commands // Only where relevant, e.g. tests agg impl, and/or front end handlers
open FsUno.UnoGame.Events // only where reelevant, e.g. tests, agg impl and/or projection layers
let [<Test>] ``Started game should be started`` () = 
    <@ UnoGame.replay [ ] 
    |> UnoGame.handle ( StartGame(3, Digit(3, Red)) )
    =[ GameStarted(3, Digit(3, Red)) ] @> 
    |> test

Support NEventStore

With a small amount of work, the sample could also persist its events in NEventStore in a SQL database.

As I'll be developing a highly similar pair of readEvents / appendEvents, I could add it here, which would serve as a nice test bed (from my perspective).

However the obvious major risk is that adding yet another front end/store (esp if its in the same lib) is going to be the straw that changes the sample from an elegant communication tool to something that misses the point.

So my (obviously very debatable) proposal is for me to split the FsUno project into

  • FsUno.Domain (unchanged domain stuff)
  • FsUno.Persistence.EventStore (ref to EventStore nuget and GES specific code)
  • FsUno.Persistence.InMemory (off on its own)
  • FsUno.DemoExe

The major plus would be that FsUno would have a lot less files and the switchable stores becomes clearer

FsUno.Tests would only depend on FsUno.Domain and use NUnit

I'd then write a FsUno.Persistence.NEventStore which FsUno.DemoExe can also reference and then you just switch the store type ref in Main. The lib would:

  • have a NES Wireup with perhaps a connection string coming in but not much else as we are not generating a storage abstraction (and when you use NES for storage only, most of the Wireup pipeline is irrelevant)
  • have a helper to create the schema if it doesnt exist (NES exposes this and it fits with this being a demo) which one would call from FsUno.DemoExe

The likelihood is that Serialization.fs would be used for Persistence.NES and Persistence.GES. I'd propose to put the file in a FsUno.Persistence but just link to it from the 2x Persistence projects.

But why oh why do all this here?

  • I love FsUno.Domain and believe any sane person should def use the approach. But there should be a really good sample which is good enough to use as-is
  • I like NEventStore (I have code in prod and am starting a new project that will use it in prod - both on Azure PaaS).
  • I like GetEventStore (and will move to it eventually)
  • I will be using the DU Serialization you've implemented but don't want to maintain a fork (but would consider using a protobuf.net or FsPickler-based swappable impl if someone contributed that)

What could I do instead?

I could create a bartelink/FunDomain repo with

  • Samples/FunUno/Domain (stolen from FsUno)
  • Samples/FunUno/Tests (xUnit+Unquote)
  • Samples/FunUno/Demo (stolen from FsUno)
  • FunDomain.Persistence.NEventStore

The problem is that I can't imagine any traction and I'd just be sowing confusion by having a fork of your serialization (and/or your GES bindings)

I hope I've explained myself sufficiently for you to decide quickly which direction you'd like this to take - open to any subsets you consider reasonable and definitely will understand if you say "Don't go toppling my nice tidy sample please!"

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.