johanvts (1) [Avatar] Offline
#1
I just spend a few hours making listing 2 compile so I thought I would upload my code here for anyone else. The main missing parts is a typo "proxyFactory" -> "ProxyFactory" and opening System namespaces:

module Model

open Castle.DynamicProxy
open System
open System.Collections.Generic
open System.ComponentModel
open [Listing 1]

[<AbstractClass>]
type Model()=
static let ProxyFactory = ProxyGenerator()
static let notifyPropertyChanged =
{new StandardInterceptor() with
member this.PostProceed invocation =
match invocation.Method, invocation.InvocationTarget with
| PropertySetter propertyName, (smilie Model as model) ->
model.TriggerPropertyChanged propertyName
| _ -> () }

let propertyChangedEvent = Event<_,_>()
interface INotifyPropertyChanged with
[<CLIEvent>]
member this.PropertyChanged = propertyChangedEvent.Publish

member internal this.TriggerPropertyChanged propertyName =
let args = PropertyChangedEventArgs propertyName
propertyChangedEvent.Trigger(this, args)

static member Create<'T when 'T :> Model and 'T : not struct>(): 'T=
let interceptors : IInterceptor[] =
[| notifyPropertyChanged; AbstractProperties() |]
ProxyFactory.CreateClassProxy interceptors

and AbstractProperties() =
let data = Dictionary()

interface IInterceptor with
member this.Intercept invocation =
match invocation.Method with
| Abstract & PropertySetter propertyName ->
data.[propertyName] <- invocation.Arguments.[0]
|Abstract & PropertyGetter propertyName ->
match data.TryGetValue propertyName with
| true, value -> invocation.ReturnValue <- value
| false, _ ->
let returnType = invocation.Method.ReturnType
if returnType.IsValueType then
let res = Activator.CreateInstance returnType
invocation.ReturnValue <- res
| _ -> invocation.Proceed()

Sorry about the missing indentation, it seems to be deleted by the forum but you can easily reconstruct it from the book listing.