Prism / Composite Application Libraryでモジュールを動的にロードする方法は?
-
07-07-2019 - |
質問
ユーザーがデータを入力するためにフォームを生成するPrism / CALアプリケーションにクラスがあります。
フォームは、次のような XML ファイルによって定義されます。
<area idCode="general" title="General">
<column>
<group title="Customer Data">
<field idCode="title" requiredStatus="true">
<label>title</label>
<fieldType>Title</fieldType>
</field>
<field idCode="firstName" requiredStatus="true">
<label>First Name</label>
<fieldType>Text</fieldType>
</field>
<field idCode="lastName" requiredStatus="true">
<label>Last Name</label>
<fieldType>Text</fieldType>
</field>
<field idCode="email" requiredStatus="true">
<label>E-Mail</label>
<fieldType>Email</fieldType>
</field>
...
</group>
</column>
</area>
フォームは、XMLの各フィールドタイプに対応する特定のコントロールを読み込む必要があります。例:
- タイトル(ドロップダウンを表示:Mr.、Mrs.、Dr。など)
- テキスト(単純なテキストボックス)
- 電子メール(電子メール検証付きのテキストボックス)
- ZipCode (郵便番号検証付きのテキストボックス)
各コントロールを個別のモジュールにして、ロードされるようにします。 ZipCode モジュールはModulesディレクトリにファイルとして存在します。
ZipCode.dll
これは、郵便番号に基づいて検証する単なるシンプルなテキストボックスコントロールですが、開発者は別のコントロールを作成できます:
ZipCodePlus.dll
同じインターフェースを継承しますが、郵便番号用のポップアップジオアースセレクターを提供します。顧客が ZipCode.dll を ZipCodePlus.dll に置き換えるとすぐに、すべてのフォームにこの new 機能郵便番号の検索用。
ただし、フォームクラスがXMLを解析するときに、コントロールに機能を提供するクラスをインスタンス化するため、これを技術的に実装する方法を視覚化するのに問題がありますが、インスタンス化クラス、参照が必要です:
SmartFormFieldZipCodePresenter smartFormFieldEmailPresenter
= container.Resolve<SmartFormFieldEmailPresenter>();
しかし、動的に、つまりクラスの名前を string としてインスタンス化するにはどうすればよいですか。そのクラスが存在しない場合、適切な< strong> exception 、たとえばこのようなもの:
擬似コード:
try {
var smartFormFieldZipCodePresenter
= container.Resolve("smartFormFieldZipCodePresenter");
}
catch (ModuleDoesNotExistException) {
...
}
解決
問題の技術的な解決策に非常に近いようです。 IZipCodePresenter
-インターフェースを作成し、ZipCode.dllまたはZipCodePlus.dllモジュールの起動時に実装を登録します。
Container.RegisterType<IZipCodePresenter, StandardZipCodePresenter>();
次に、パーサーで、次のようにインスタンスを解決します:
var zipCodePresenter = container.Resolve<IZipCodePresenter>();
インターフェイスにインスタンスが登録されていない場合、例外がスローされます。それ以外の場合は、IZipCodePresenterの最後に登録された具象実装を取得します。例外は、インターフェイスを登録しようとした場合にのみスローされることに注意してください。クラスをUnityに登録しようとすると、Lifetime Managerポリシーに基づいてインスタンスが作成されます。
これをさらに進めたい場合は、IDynamicPresenterのようなインターフェイスを作成できます。その後、既知の文字列(インフラストラクチャプロジェクトで定義)に基づいて登録できます。
Container.RegisterType<IDynamicPresenter, StandardZipCodePresenter>(PresenterName.ZipCodeControl);
Container.RegisterType<IDynamicPresenter, StandardEmailPresenter>(PresenterName.EmailControl);
そして次のように解決します:
var zipCodeControl = Container.Resolve<IDynamicPresenter>(PresenterName.ZipCodeControl);
var emailControl = Container.Resolve<IDynamicPresenter>(PresenterName.EmailControl);
前者のソリューションの方が好きですが、これは確かに有効なオプションです。
これがお役に立てば幸いです!
P.s。これはおもしろいアイデアのように聞こえます...実装をどのように行っているか聞いてみたいです。さらに一歩進んで、ASP.NET MVCの概念に基づいてXAMLビルダーフレームワーク全体を作成することもできます。テストの容易さを促進しながら、WPFの力を発揮できます。がんばって!