Выдача сгенерированных типов в поставщиках типов F#

Я создал простой генерирующий поставщик типов, который выбирает путь к сборке при реорганизации типов, чтобы поместить их в пространство имен поставщиков типов (что-то вроде интернализации, если хотите).

Ссылка на соответствующий код находится здесь https://github.com/colinbull/Playground.

Теперь типы кажутся правильными,

let[<Literal>]assemblyPath = @"D:\Appdev\Playground\SimpleLib\bin\Debug\SimpleLib.dll"
type T = Inno.InternalisingProvider<assemblyPath>
type C = T.Class1

[<EntryPoint>]
let main argv = 
    let c = new C()
    printfn "Result: %A" c.X
    System.Console.ReadLine() |> ignore
    0

так как отображаются в VS без каких-либо сообщений об ошибках. Однако, когда я компилирую эту сборку, кажется, что IL выдается неправильно со следующей ошибкой.

Ошибка 1: возникла проблема при записи двоичного файла «obj\Debug\TypeProviders.Tests.exe»: ошибка в pass3 для типа Program, ошибка: ошибка в GetMethodRefAsMethodDefIdx для mref = «.ctor», ошибка: исключение типа «Microsoft.FSharp». .Compiler.AbstractIL.ILBinaryWriter+MethodDefNotFound». FSC 1 1 TypeProviders.Tests

Примеры для сгенерированных типов, приведенные в примерах, похоже, не имеют любой определенный StaticParameters, который требует возврата типа с предоставленным именем типа. В этом случае, как мне выделить типы в предоставленной сборке? В настоящее время я делаю следующее

  let provideAssembly (reqType:ProvidedTypeDefinition) assemblyPath =
      let name = Path.GetFileName(assemblyPath)
      let providedAssembly = ProvidedAssembly.RegisterGenerated(assemblyPath)

      for t in providedAssembly.GetExportedTypes() do
          let ty = createGeneratedType t
          ty.SetAssembly(providedAssembly)
          reqType.AddMember(ty)

      reqType

заранее спасибо


person Colin Bull    schedule 25.02.2013    source источник


Ответы (1)


Отказ от ответственности: решения, скомпилированные браузером

Я считаю, что здесь вам не нужно создавать сгенерированные типы, которые будут обертывать существующие типы => это должно работать

let provideAssembly (reqType:ProvidedTypeDefinition) assemblyPath =
    let existingAssembly = Assembly.LoadFrom(assemblyPath)

    for ty in providedAssembly.GetExportedTypes() do
        reqType.AddMember(ty)

    reqType

Вы также можете попробовать это:

let provideAssembly (reqType:ProvidedTypeDefinition) assemblyPath =
    reqType.AddAssemblyTypesAsNestedTypesDelayed(fun() -> Assembly.LoadFrom assemblyPath)
    reqType

этот сохранит пространство имен, поэтому объявление типа C будет выглядеть так

type C = T.SimpleLib.Class1
person desco    schedule 26.02.2013
comment
Боже, я такой глупый, я попробовал это первым, но поместил прямую ссылку на сгенерированный тип в свой код, поэтому тогда я получал ошибки компиляции. Усвоенный урок -› правильно читайте сообщения об ошибках. Еще раз спасибо - person Colin Bull; 26.02.2013