2009-09-14 57 views
2

我有一個在我的棱鏡/ CAL應用程序生成一個表格供用戶填寫數據。如何在Prism/Composite Application Library中動態加載模塊?

形式由一個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,例如

  • 標題(顯示一個下拉:先生,女士,博士等)
  • 文本(簡易文本)
  • 電子郵件(文本框與電子郵件確認)
  • 郵編(文本框與郵編驗證)

我想讓每個控件都是一個單獨的模塊,它會被加載,例如,在郵編模塊將在模塊目錄中的文件:

ZipCode.dll 

這僅僅是一個簡單的文本框控制基於郵政編碼,用於驗證,但開發人員可以創建一個名爲另一個控制:

ZipCodePlus.dll 

繼承了相同的接口但提供用於郵編彈出地理大地選擇器。只要客戶更換ZipCode.dllZipCodePlus.dll,他所有的形式將這個功能用於搜索郵政編碼。

但是,我很難想象這將如何在技術上實現,因爲當我的表單類解析XML時,它實例化了爲控件提供功能的類,但是爲了實例化類,我必須有一個參考它:

SmartFormFieldZipCodePresenter smartFormFieldEmailPresenter 
    = container.Resolve<SmartFormFieldEmailPresenter>(); 

但我怎麼能以班級爲的名稱進行實例化動態,即,如果該類不存在,它會拋出一個approp riate 例外,例如是這樣的:

僞代碼:

try { 
    var smartFormFieldZipCodePresenter 
     = container.Resolve("smartFormFieldZipCodePresenter"); 
} 
catch (ModuleDoesNotExistException) { 
    ... 
} 
+0

你正在使用什麼樣的解析器。是延遲加載還是急切加載。我們也在使用類似的方法。 – Mohanavel 2011-01-11 04:37:34

回答

3

看來你是非常接近的技術解決您的問題。我會簡單地創建一個接口 - 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的力量。祝你好運!