1

次のコードを実行すると、F#WPFテンプレートのプロジェクトで、NugetPrismが追加されます

module MainApp

open System
open System.Windows
open System.Windows.Controls
open Microsoft.Practices.Unity
open Microsoft.Practices.Prism.UnityExtensions;
open FSharpx

type Shell = XAML<"MainWindow.xaml">

type App () =
   inherit Application()

   override x.OnStartup e =
      base.OnStartup(e);
      let bt = new BootStrapper()
      bt.Run()

and  BootStrapper () = 
   inherit UnityBootstrapper()

   override x.CreateShell() = 
     let a = x.Container.Resolve<Shell>()

     let b = a.Root
     b :> DependencyObject

   override x.InitializeShell()= 
         base.InitializeShell();
         App.Current.MainWindow <- x.Shell :?> Window
         App.Current.MainWindow.Show()


[<STAThread>]
(new App()).Run() |> ignore

コンパイル時にエラーは発生しませんが、実行時にa.RootがFrameworkElementであり、ウィンドウにキャストできないという例外があります。

デバッグすると、「a」のランタイムコンテンツは、XAMLタイププロバイダーの内部表現である{FSharpx.TypeProviders.XamlProvider.XamlFile}と同じタイプであり、その内部ディクショナリは空であることがわかります。

TPの内部表現が表面化することになっているのかわかりません。タイププロバイダーのメカニズムがUnityによって無視されているように見えます。Unityがリフレクションを使って依存関係を理解し​​ているように見えるからだと思います。

TPを使用して同様の動作を経験し、光を当てることができる人はいますか?

PS:F#でのこの不一致のコンパイル/ランタイムは非常に驚くべきものです。それには正当な理由があるに違いありませんが、私はそのような出来事の可能性を忘れていました!

4

1 に答える 1

3

FSharpXソースコードでわかるように、Xamlタイププロバイダーは1つ消去されます。メタデータのようにシェルタイプはありません。このタイプで機能するものはすべて、ベースタイプであるXamlFileの操作に対して消去されます。したがって、この

let a = x.Container.Resolve<Shell>()

のようにsmthに消去されます

let a = x.Container.Resolve<XamlFile>()

したがって、UnityはXamlFileの新しいインスタンスを作成するだけです。対照的に、シェルを直接インスタンス化しようとすると、F#コンパイラは提供されたコンストラクタを使用するため、

let a = Shell()

効果的に意味します

let a = XamlFile(XamlReader.Parse( <content-of-xaml-file> ))

あなたの場合、おそらくシェルをインスタンス化してから、x.Container.BuildUp()を使用してその内部にデータを入力できます。

type App () =
   inherit Application()

   override x.OnStartup e =
      base.OnStartup(e);
      let bt = new BootStrapper()
      bt.Run()

and  BootStrapper () = 
   inherit UnityBootstrapper()

   override x.CreateShell() = 
     let a = Shell()
     x.Container.BuildUp(a.Root) :> _

   override x.InitializeShell()= 
         base.InitializeShell();
         App.Current.MainWindow <- x.Shell :?> Window
         App.Current.MainWindow.Show()


[<STAThread>]
(new App()).Run() |> ignore
于 2012-08-19T18:05:15.600 に答える