5 people like it.

Interface workaround for circular dependency problem

Interface workaround for circular dependency problem

 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: 
namespace Ijs

open System.Runtime.InteropServices

type IEnvironment =
  interface
    abstract Undefined : unit -> IUndefined with get
    abstract Operators : unit -> IOperators with get
    abstract Globals : unit -> ICommonObject with get
  end

and ICommonObject =
  interface
    
    abstract Environment : unit -> IEnvironment with get
    abstract Put : string * BoxedValue -> unit
    abstract Get : string -> BoxedValue
    abstract Has : string -> BoxedValue
    abstract Call : ICommonObject * BoxedValue array -> BoxedValue

  end

and IUndefined =
  interface
    abstract AccessAddOperator : unit -> BoxedValue
  end

and IOperators =
  interface
    abstract Add : BoxedValue * BoxedValue -> BoxedValue
  end

and [<NoComparison>] [<StructLayout(LayoutKind.Explicit)>] BoxedValue =
  struct
    [<FieldOffset(0)>] val mutable Number : float
    [<FieldOffset(8)>] val mutable Object : obj
  end

// Imaginary file end here, and new file starts below
// notice that these types are not recursive and can be
// split over several files

type Undefined(env:IEnvironment) =
  class
    interface IUndefined with
      member x.AccessAddOperator() =
        env.Operators.Add(BoxedValue(), BoxedValue())
  end

type Operators() =
  class
    interface IOperators with
      member x.Add (left:BoxedValue, right:BoxedValue) = left
  end

type Environment(globals:ICommonObject) as x =
  
  let undefined = Undefined(x) :> IUndefined
  let operators = Operators() :> IOperators

  interface IEnvironment with
    member x.Globals = globals
    member x.Operators = operators
    member x.Undefined = undefined
namespace System
namespace System.Runtime
namespace System.Runtime.InteropServices
type IEnvironment =
  interface
    abstract member Globals : ICommonObject
    abstract member Operators : IOperators
    abstract member Undefined : IUndefined
  end

Full name: Ijs.IEnvironment
abstract member IEnvironment.Undefined : IUndefined

Full name: Ijs.IEnvironment.Undefined
type unit = Unit

Full name: Microsoft.FSharp.Core.unit
type IUndefined =
  interface
    abstract member AccessAddOperator : unit -> BoxedValue
  end

Full name: Ijs.IUndefined
Multiple items
abstract member IEnvironment.Operators : IOperators

Full name: Ijs.IEnvironment.Operators

--------------------
module Operators

from Microsoft.FSharp.Core
type IOperators =
  interface
    abstract member Add : BoxedValue * BoxedValue -> BoxedValue
  end

Full name: Ijs.IOperators
abstract member IEnvironment.Globals : ICommonObject

Full name: Ijs.IEnvironment.Globals
type ICommonObject =
  interface
    abstract member Call : ICommonObject * BoxedValue array -> BoxedValue
    abstract member Get : string -> BoxedValue
    abstract member Has : string -> BoxedValue
    abstract member Put : string * BoxedValue -> unit
    abstract member Environment : IEnvironment
  end

Full name: Ijs.ICommonObject
abstract member ICommonObject.Environment : IEnvironment

Full name: Ijs.ICommonObject.Environment
abstract member ICommonObject.Put : string * BoxedValue -> unit

Full name: Ijs.ICommonObject.Put
Multiple items
val string : value:'T -> string

Full name: Microsoft.FSharp.Core.Operators.string

--------------------
type string = System.String

Full name: Microsoft.FSharp.Core.string
type BoxedValue =
  struct
    val mutable Number: float
    val mutable Object: obj
  end

Full name: Ijs.BoxedValue
abstract member ICommonObject.Get : string -> BoxedValue

Full name: Ijs.ICommonObject.Get
abstract member ICommonObject.Has : string -> BoxedValue

Full name: Ijs.ICommonObject.Has
abstract member ICommonObject.Call : ICommonObject * BoxedValue array -> BoxedValue

Full name: Ijs.ICommonObject.Call
type 'T array = 'T []

Full name: Microsoft.FSharp.Core.array<_>
abstract member IUndefined.AccessAddOperator : unit -> BoxedValue

Full name: Ijs.IUndefined.AccessAddOperator
abstract member IOperators.Add : BoxedValue * BoxedValue -> BoxedValue

Full name: Ijs.IOperators.Add
Multiple items
type NoComparisonAttribute =
  inherit Attribute
  new : unit -> NoComparisonAttribute

Full name: Microsoft.FSharp.Core.NoComparisonAttribute

--------------------
new : unit -> NoComparisonAttribute
Multiple items
type StructLayoutAttribute =
  inherit Attribute
  new : layoutKind:LayoutKind -> StructLayoutAttribute + 1 overload
  val Pack : int
  val Size : int
  val CharSet : CharSet
  member Value : LayoutKind

Full name: System.Runtime.InteropServices.StructLayoutAttribute

--------------------
StructLayoutAttribute(layoutKind: LayoutKind) : unit
StructLayoutAttribute(layoutKind: int16) : unit
type LayoutKind =
  | Sequential = 0
  | Explicit = 2
  | Auto = 3

Full name: System.Runtime.InteropServices.LayoutKind
field LayoutKind.Explicit = 2
Multiple items
type FieldOffsetAttribute =
  inherit Attribute
  new : offset:int -> FieldOffsetAttribute
  member Value : int

Full name: System.Runtime.InteropServices.FieldOffsetAttribute

--------------------
FieldOffsetAttribute(offset: int) : unit
BoxedValue.Number: float
Multiple items
val float : value:'T -> float (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.float

--------------------
type float = System.Double

Full name: Microsoft.FSharp.Core.float

--------------------
type float<'Measure> = float

Full name: Microsoft.FSharp.Core.float<_>
BoxedValue.Object: obj
type obj = System.Object

Full name: Microsoft.FSharp.Core.obj
Multiple items
type Undefined =
  interface IUndefined
  new : env:IEnvironment -> Undefined

Full name: Ijs.Undefined

--------------------
new : env:IEnvironment -> Undefined
val env : IEnvironment
val x : Undefined
override Undefined.AccessAddOperator : unit -> BoxedValue

Full name: Ijs.Undefined.AccessAddOperator
property IEnvironment.Operators: IOperators
abstract member IOperators.Add : BoxedValue * BoxedValue -> BoxedValue
Multiple items
module Operators

from Microsoft.FSharp.Core

--------------------
type Operators =
  interface IOperators
  new : unit -> Operators

Full name: Ijs.Operators

--------------------
new : unit -> Operators
val x : Operators
override Operators.Add : left:BoxedValue * right:BoxedValue -> BoxedValue

Full name: Ijs.Operators.Add
val left : BoxedValue
val right : BoxedValue
Multiple items
type Environment =
  interface IEnvironment
  new : globals:ICommonObject -> Environment

Full name: Ijs.Environment

--------------------
new : globals:ICommonObject -> Environment
val globals : ICommonObject
val x : Environment
val undefined : IUndefined
val operators : IOperators
override Environment.Globals : ICommonObject

Full name: Ijs.Environment.Globals
Multiple items
override Environment.Operators : IOperators

Full name: Ijs.Environment.Operators

--------------------
module Operators

from Microsoft.FSharp.Core

--------------------
type Operators =
  interface IOperators
  new : unit -> Operators

Full name: Ijs.Operators

--------------------
new : unit -> Operators
Multiple items
override Environment.Undefined : IUndefined

Full name: Ijs.Environment.Undefined

--------------------
type Undefined =
  interface IUndefined
  new : env:IEnvironment -> Undefined

Full name: Ijs.Undefined

--------------------
new : env:IEnvironment -> Undefined
Raw view Test code New version

More information

Link:http://fssnip.net/6b
Posted:13 years ago
Author:fholm
Tags: interface , workaround