Ich arbeite an einem Prototyp, um eine Dokumentendatenbank zu verwenden (derzeit MongoDB, kann sich ändern) und fand die .NET-Treiber ein wenig Schmerz, also dachte ich, ich würde den Datenzugriff mit dem Repository abstrahieren Muster. Das sollte es einfach machen, den Treiber, den ich gerade benutze (NoRM, mongodb-csharp, simple-mongob), mit auszutauschen, den Killer f # mongodb-Treiber, der nicht lutscht, wenn er fertig ist.Repository-Muster in F #
Meine Frage ist um die Hinzufügen Operation. Dies wird einige Seiteneffekte auf die Datenbank haben und somit werden nachfolgende Aufrufe an Alle unterschiedlich sein. Kümmert mich das? In C# würde ich das traditionell nicht machen, aber ich fühle, dass in F # ich sollte.
ist die generische Repository-Schnittstelle:
type IRepository<'a> =
interface
abstract member All : unit -> seq<'a>
// Add has a side-effect of modifying the database
abstract member Add : 'a -> unit
end
Und hier ist wie eine MongoDB Implementierung aussieht:
type Repository<'b when 'b : not struct>(server:MongoDB.IMongo,database) =
interface IRepository<'b> with
member x.All() =
// connect and return all
member x.Add(document:'b) =
// add and return unit
In der gesamten App I IRepository verwenden, so dass es leicht Treiber zu ändern und potenziell Datenbanken.
Calling All ist in Ordnung, aber mit Hinzufügen, was ich gehofft hatte, war anstatt eine Einheit zurückzugeben, eine neue Repository-Instanz zurückgeben. Etwas wie:
Das Problem ist, dass, wenn ich Get aufrufen, dann hinzufügen, das ursprüngliche Repository immer noch alle Dokumente zurückgibt. Beispiel:
let repo1 = new Repository<Question>(server,"killerapp") :> IRepository<Question>
let a1 = repo1.All()
let repo2 = repo1.Add(new Question("Repository pattern in F#"))
let a2 = repo2.All()
Idealerweise möchte ich Länge von a1 und a2, anders zu sein, aber sie sind die gleichen wie sie beide die Datenbank getroffen. Die Anwendung funktioniert, Benutzer können ihre Frage stellen, aber der Programmierer fragt sich, warum er ein neues IRepository zurückgibt.
Also sollte ich versuchen, den Nebeneffekt von Add auf der Datenbank im Design der Typen zu behandeln? Wie würden andere dies tun, verwenden Sie ein Repository oder eine solche Interface-Klasse oder haben Sie einen besseren funktionalen Ansatz?
Worüber Sie MongoDB nicht unterstützt, aber die Idee ist immer noch interessant, und mindestens eine Implementierung existiert. Werfen Sie einen Blick auf http://www.datomic.com/. –