2010-12-02 17 views
2

私は、既存のSilverlightアプリケーションへのPagesの動的ロードの実装に取り​​組んでいます。ここまでは順調ですね。外部の.xapの作業からページをインポートしたり、ホストアプリケーションからプラグインにデータをエクスポートしたりするのは機能しています。MEFの外部のタイプのインポート/インポート - Silverlight

ホストアプリケーションは、バックエンドシステムに関連するさまざまなタイプを公開するWebサービスを使用します。私の質問は、Webサービスで定義されたタイプのオブジェクトをどのようにエクスポートするのですか?

例i WSクライアントで定義されているSMS_SupportedPlatformsのリストをエクスポートします。これはホスティングアプリケーションからのものです。このプロパティは、SilverlightアプリケーションのApp.xaml.csに存在します。これは、Webサービスへの非同期呼び出しによって満たされます。

[Export(ExportContracts.SMS_SupportedPlatforms)] 
    public static List<Client.SMS_SupportedPlatforms> SupportedPlatforms = new List<Client.SMS_SupportedPlatforms>(); 

編集:私は、外部のアセンブリに洗面所独立クラスへの輸入を移動した 。彼らは今、このクラスでrecide:

public class NeoServiceManagerImports 
{ 
     [Import(NeoSMExportContracts.DepartmentExportAttribute, AllowRecomposition = true)] 
     public string Department { get; set; } 

     [Import(NeoSMExportContracts.RolesExportAttribute, AllowRecomposition = true)] 
     public List<string> Roles { get; set; } 



     [Import(NeoSMExportContracts.SMS_SupportedPlatforms, AllowRecomposition = true)] 
     public List<Client.SMS_SupportedPlatforms> SupportedPlatforms 
     { 
      get; 
      set; 
     } 

     public NeoServiceManagerImports() 
     { 
      CompositionInitializer.SatisfyImports(this); 
     } 

}

(テスト目的のために)エクスポートされるページのコンストラクタで呼ばれるこのクラス。 その後、MetadataAttributeを使ってページをUIProviderbaseクラスにエクスポートします。プラグインをエクスポートするためにバインドしました。(非常に抽象的な名前を無視します;-))クラスには、ロゴ、タイトル、およびページのリスト用の2つの小道具があります。

[Export(typeof(UIProviderBase))] 
    public class ExternalMainMenuExternalSubMenuUIProvider: UIProviderBase 
    { 

     public override string Title 
     { 
      get { return "Submenu"; } 
     } 

     public override string ImageUri 
     { 
      get { return "uriuri"; } 
     } 

     [ImportMany("ExternalSubMenuForExternalMainMenuContract")] 
     public override List<System.ComponentModel.Composition.ExportFactory<FrameworkElement, IPageMetadata>> EntryPage 
     { 
      get; 
      set; 
     } 
    } 

Iわから問題は、MEFは、2つの異なるアセンブリによって参照されていると同じタイプを、解決することができないことにも関します。 ISMS_SupportedPlatformsのリストを取得するためにホスティング・アプリケーションをリファクタリングせずに、これを解決する方法はありますか?現在、ホスティングアプリケーションは正しくエクスポートされているようですが、プラグインでは検出されません。

AllowDefault = trueの場合、ページはロードされますがSupportedPlatformsはnullのままです。 falseの場合、ページをエクスポートせずにサイレントモードで失敗します。

私はページの読み込み方法を少し変えました。私はあなたのためにいくつかの情報を得ようとしています。これは私が今

The composition produced a single composition error. The root cause is provided below. Review the CompositionException.Errors property for more detailed information. 

1) No valid exports were found that match the constraint '((exportDefinition.ContractName == "SMS_SupportPlatformsExport") AndAlso (exportDefinition.Metadata.ContainsKey("ExportTypeIdentity") AndAlso "System.Collections.Generic.List(HelloWorld.MEF.Client.SMS_SupportedPlatforms)".Equals(exportDefinition.Metadata.get_Item("ExportTypeIdentity"))))', invalid exports may have been rejected. 

Resulting in: Cannot set import 'HelloWorld.MEF.NeoServiceManagerImports.SupportedPlatforms (ContractName="SMS_SupportPlatformsExport")' on part 'HelloWorld.MEF.NeoServiceManagerImports'. 
Element: HelloWorld.MEF.NeoServiceManagerImports.SupportedPlatforms (ContractName="SMS_SupportPlatformsExport") --> HelloWorld.MEF.NeoServiceManagerImports 

Resulting in: An exception occurred while trying to create an instance of type 'HelloWorld.MEF.ExternalMainMenuExternalSubMenu'. 

Resulting in: Cannot activate part 'HelloWorld.MEF.ExternalMainMenuExternalSubMenu'. 
Element: HelloWorld.MEF.ExternalMainMenuExternalSubMenu --> HelloWorld.MEF.ExternalMainMenuExternalSubMenu --> AssemblyCatalog (Assembly="HelloWorld.MEF, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null") 

Resulting in: Cannot get export 'HelloWorld.MEF.ExternalMainMenuExternalSubMenu (ContractName="ExternalSubMenuForExternalMainMenuContract")' from part 'HelloWorld.MEF.ExternalMainMenuExternalSubMenu'. 
Element: HelloWorld.MEF.ExternalMainMenuExternalSubMenu (ContractName="ExternalSubMenuForExternalMainMenuContract") --> HelloWorld.MEF.ExternalMainMenuExternalSubMenu --> AssemblyCatalog (Assembly="HelloWorld.MEF, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null") 

これは、例外は

var page = (from p in this.Plugins 
        from e in p.EntryPage 
        where e.Metadata.NavigateUri == this.targetUri.ToString() 
        select e).Single().CreateExport().Value; 

を要約すると

public class MefContentLoader : INavigationContentLoader 
    { 
     private PageResourceContentLoader pageResourceContentLoader = new PageResourceContentLoader(); 
     private Uri targetUri; 

     [ImportMany(AllowRecomposition = true)] 
     public UIProviderBase[] Plugins 
     { 
      get; 
      set; 
     } 

     public MefContentLoader() 
     { 
      CompositionInitializer.SatisfyImports(this); 
     } 

     #region INavigationContentLoader Members 

     public IAsyncResult BeginLoad(Uri targetUri, Uri currentUri, AsyncCallback userCallback, object asyncState) 
     { 
      this.targetUri = targetUri; 
      return pageResourceContentLoader.BeginLoad(targetUri, currentUri, userCallback, asyncState); 
     } 

     public bool CanLoad(Uri targetUri, Uri currentUri) 
     { 
      // TODO: Handle this properly 
      return true; 
     } 

     public void CancelLoad(IAsyncResult asyncResult) 
     { 
      // TODO: Handle this properly 
      pageResourceContentLoader.CancelLoad(asyncResult); 
     } 

     public LoadResult EndLoad(IAsyncResult asyncResult) 
     { 
      if (this.Plugins.Length == 0 || 
       this.Plugins.Count(p => p.EntryPage != null && p.EntryPage.Any(u => u.Metadata.NavigateUri == targetUri.ToString())) == 0) 
      { 
       return pageResourceContentLoader.EndLoad(asyncResult); 
      } 

      var page = (from p in this.Plugins 
        from e in p.EntryPage 
        where e.Metadata.NavigateUri == this.targetUri.ToString() 
        select e).Single().CreateExport().Value; 

      return new LoadResult(page); 
     } 

     #endregion 


    } 

(動的にページをロードする)このクラス在住表示されたコードが表示されるエラーです: アセンブリB(プラグイン)で、アセンブリBのUIProviderbaseにいくつかのページをエクスポートしています。アセンブリからのデータを消費する必要がありますA(メインのSilverlightアプリ)アセンブリAはUIProviderbaseをプラグインとしてインポートし、それらからアプリケーションにそれらを追加する一連のメニューページを取得する必要があります。 これは、Webサービスで定義されているタイプ以外のすべてで動作します。アセンブリAとBの両方に参照があります。

+0

実際に見ている動作は何ですか?何が間違っているかを私に伝えるのに十分な情報はありませんが、この問題はマッチングしていないタイプと関係しているとは思えません。 –

+0

こんにちはダニエル。 AllowDefault = trueの場合、ページはレンダリングされますが、SupportedPlatformsはnullです。そうでない場合、ページはエクスポートとしてまったくマークされません。 – anders

+0

ダニエル、これをもう一度見たいと思ったら。私はいくつかの情報を追加しました:) – anders

答えて

1

は、タイプマッチングやタイプの非互換性のいずれかのいくつかのフォームだった、が判明します。プラグイン(アセンブリB)では、私は国会Aへの参照を追加し、そこからタイプを使用:

[Import(AllowRecomposition = true)] 
public Lazy<List<NeoServiceManager.Client.SMS_SupportedPlatforms>> SupportedPlatforms 
{ 
    get; 
    set; 
} 

それはこの場合には必要ではないですので、私は、ContractNameでエクスポートまたはインポートを飾っておらず、タイプは曖昧ではありません。

0

あなたのListプロパティはどこにありますか?

使用しよう:

Container.GetExportedValues<Client.SMS_SupportedPlatforms>() 
+0

元の投稿を更新しました。もっとコードを投稿すべきですか? – anders

+0

それはエクスポートされているようです:http://yfrog.com/nfsampleyp – anders

関連する問題