My favorites | Sign in
Project Home Downloads Wiki Issues Source
Repository:
Checkout   Browse   Changes   Clones    
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#light

namespace Yadic

open System;;
open System.Linq;;
open System.Reflection;;
open System.Collections.Generic;;

type public ContainerException(s) =
inherit Exception(s)

type IContainer =
abstract Add<'T> : unit -> unit
abstract Add<'Interface, 'Component> : unit -> unit
abstract Add<'T> : Func<obj> -> unit
abstract Resolve<'T> : unit -> 'T
abstract Resolve : Type -> obj
abstract Decorate<'Interface, 'Component> : unit -> unit

type IActivator =
abstract Activate: unit -> obj

type LazyActivator(activator:unit->obj) =
let instance = lazy( activator() )

interface IActivator with
member this.Activate() = instance.Force()


type SimpleContainer(missingHandler:Func<Type,obj>) =
let activators = new Dictionary<Type, IActivator>()

let resolve t =
match activators.ContainsKey(t) with
| true -> activators.[t].Activate()
| false -> t |> missingHandler.Invoke

let createInstance (t:Type, resolver:(Type -> obj) ) =
let sortedConstructors = t.GetConstructors() |> Array.sortBy(fun c -> -c.GetParameters().Length)
let result = sortedConstructors |> Array.tryPick( fun c ->
try
let instances = c.GetParameters() |> Array.map( fun p -> resolver(p.ParameterType) )
Some(Activator.CreateInstance(t, instances))
with | :? ContainerException -> None )
match result with
| Some(instance) -> instance
| None -> raise( new ContainerException(t.ToString() + " does not have a satisfiable constructor"))

let create (t:Type) = createInstance(t, resolve)

let addActivator (t,f) =
match activators.ContainsKey(t) with
| true -> raise( new ContainerException(t.ToString() + " already added to container"))
| false -> activators.Add(t, new LazyActivator(f))

let add (i,c) =
addActivator (i, fun() -> create(c) )

let decorate (i,c) =
let existing = activators.[i]
activators.[i] <- new LazyActivator(fun() ->
createInstance(c, fun t ->
if t.Equals(i) then existing.Activate() else resolve(t)))

new() = SimpleContainer(fun (t) -> raise ( new ContainerException(t.ToString() + " not found in container") ))

interface IContainer with
member this.Add<'T>() = (typeof<'T>,typeof<'T>) |> add
member this.Add<'Interface,'Component>() = (typeof<'Interface>,typeof<'Component>) |> add
member this.Add<'T>(f) = (typeof<'T>, fun () -> f.Invoke() ) |> addActivator
member this.Resolve<'T>() = typeof<'T> |> resolve :?> 'T
member this.Resolve(t) = t |> resolve
member this.Decorate<'Interface,'Decorator>() = (typeof<'Interface>,typeof<'Decorator>) |> decorate

Change log

f41433a865d5 by d...@bodar.com on Dec 4, 2009   Diff
Updated FSharp version and removed
unneeded attributes
Go to: 

Older revisions

9879424b08f5 by d...@bodar.com on Nov 30, 2009   Diff
Moved dotNet project to root
a2ca12c04300 by d...@mini-laptop on Sep 19, 2009   Diff
Now throws when no constructor is
satifiable
1e169b992d8e by d...@bodar.com on Sep 16, 2009   Diff
Made dotNet version ThreadSafe as well
All revisions of this file

File info

Size: 2558 bytes, 75 lines
Powered by Google Project Hosting