Ошибка реализации шаблона Singleton (внутри взаимно рекурсивных типов) - PullRequest
0 голосов
/ 24 марта 2011

Я пытаюсь реализовать шаблон синглтона, но получаю сообщение об ошибке. Моя реализация выглядит функционально идентичной этому ответу и этому . Я использую класс вместо модуля, потому что он реализует интерфейс.

type SystemObjectFactory private () =
    static let instance = lazy ( SystemObjectFactory() )
    static member Instance = instance.Value //ERROR

Исключение составляет:

System.InvalidOperationException: статическая инициализация файла или типа приводила к рекурсивному доступу к статическим данным до их полной инициализации.

Как я могу это исправить?

В качестве примечания, я не уверен, почему следующее (что я предпочитаю) тоже не работает:

type SystemObjectFactory private () =
    static let instance = SystemObjectFactory()
    static member Instance = instance

UPDATE

Возможно, я обнаружил проблему. На этот класс ссылаются из статического конструктора взаимно рекурсивного типа. Видимо, это темная и запрещенная магия в .NET.

Больше контекста:

type Entity() =
    static do
        Bootstrapper(SystemObjectFactory.Instance).Init() //PURE EVIL

and SystemObjectFactory private () =
    static let instance = SystemObjectFactory()
    static member Instance = instance

1 Ответ

2 голосов
/ 24 марта 2011

Каким образом предпочитаемая вами версия не работает? Когда я набираю его в FSI, это похоже на работу:

> type SystemObjectFactory private () =
    static let instance = SystemObjectFactory()
    static member Instance = instance;;

type SystemObjectFactory =
  class
    private new : unit -> SystemObjectFactory
    static member Instance : SystemObjectFactory
  end

> SystemObjectFactory.Instance;;
val it : SystemObjectFactory = FSI_0002+SystemObjectFactory

Обновление

Попробуйте изменить порядок ваших рекурсивных типов!

type SystemObjectFactory private () =
    static let instance = SystemObjectFactory()
    static member Instance = instance
and Entity() =
    static do
        SystemObjectFactory.Instance = SystemObjectFactory.Instance |> ignore //slightly evil
...