Way to record changes to an object using F#
Is there a clever way to record changes made to an object in F#?
I have been researching F# as a way to build an object model that replicates itself over the networ开发者_JAVA百科k. One task I need to solve is how to detect changes made to objects so I can send only changes to clients
Note: I am looking for answers other than "implement INotifyPropertyChanged" or "do something that can easily be done in C#". If that is the only way to solve the problem in F# then F# is not the tool im looking for.
Why F#? Because I am not satisfied with the ways this state observer pattern is implemented in C#. Hence I am investigating if there is some elegant way to implement it in a dynamic language, starting with F#.
Instead of detecting and notifying changes as they happen, you could make your classes immutable (for example by using the standard immutable types like records and unions, or by making the object contain only immutable things). Then you could write a function that "diffs" two instances of a class, and have some agent that looks for changes on a schedule or based on some trigger and sends the diffs to the other end.
Because the data would be immutable, the agent would only need to retain a pointer to the version it last sent. The diffing function itself could either be written by hand for each class, which would allow for an efficient implementation that takes the properties of the data into account, or you could write a generic one using reflection.
An example of INotifyPropertyChanged
use in F#.
type DemoCustomer() =
let mutable someValue = 0
let propertyChanged = Event<_, _>()
member this.MyProperty
with get() = someValue
and set(x) =
someValue <- x
propertyChanged.Trigger(this, PropertyChangedEventArgs("MyProperty"))
interface INotifyPropertyChanged with
[<CLIEvent>]
member this.PropertyChanged = propertyChanged.Publish
How about using the INotifyPropertyChanged interface? and raise events that cause the data to be replicated when it is changed?
I'd use a proxy library: Castle DynamicProxy, LinFu, Spring.NET, etc.
Using a proxy library you can easily implement INotifyPropertyChanged in a transparent, non-invasive way.
Can you use reflection to walk the object fields and see what changed? If they contain immutable F# data then equality checks will pick up the changes. You can then send the diffs relative to the last sent object.
精彩评论