2014-01-15 10 views
8

現在、プラグインを使用したMicrosoft Dynamics CRMの拡張を開始しています。MS Dynamics CRMの依存性注入

これらのプラグインに依存性注入を追加することは可能ですか(テスト、疎結合などの目的)? IoCコンテナを登録する場所はどこですか?同じタイプのすべてのプラグインで使用されていますか? CRMで

+0

を説明する小さな例を参照してください。 //ideas.dynamics.com/ideas/dynamics-crm/814208 –

答えて

5

私たちはDynamics CRMアプリケーションで単体テストを行い、依存関係注入を試みてきました。残念ながら、マイクロソフトのサポートとコンサルタントが確認されているので、サポートする方法はありません。プラグインのビジネスロジックをすべて別のビジネスクラスに移して、依存関係注入を適用するか、それについて考えるのをやめてください。

ダイナミックCRMを使用して対抗する場合は、DIコンテナとなるプラグインスーパークラスに静的フィールドを定義する必要があります。次のようにMicrosoftは、単に私たちは、彼らが内部で使用しているIServiceProviderの実装にはいくつかのコンポーネントを登録できませんなぜ、

public abstract class SuperPlugin : IPlugin{ 
     public void Execute(IServiceProvider serviceProvider){ 
      // initialize a static container instance if not available 
      var containerWrapper = new ContainerWrapper{ 
       Container = serviceProvider.GetService(typeof(IPluginExecutionContext)), 
       Resolver = //static resolver instance of dependency container 
      }; 
      OnExecution(containerWrapper); 
     } 
     public abstract void OnExecution(IDependencyResolver resolver); 
} 

私は本当に理解することはできません。

ps。SuperPluginクラスはIPluginなので、サブクラスにインターフェイス実装を書くのを忘れるかもしれません。しかし、公式のDynamics CRM SDKに同梱されているPlugin Registrationツールのバグがありました。だから、編集

public class MyPlugin : SuperPlugin, IPlugin{ 
    public abstract void OnExecution(IDependencyResolver resolver){}; 
} 

、あなたは次のようにまた、あなたのプラグインを実装する必要があり、同じ問題を抱えているかもしれ場合:あなたがhttpsに、この機能のために投票することができます概念 https://github.com/nakahparis/DIForCRM

+0

すてきな回避策。依存関係リゾルバをどのようにインスタンス化しますか?静的クラスまたはシングルトン構造を使用していますか?私は静的リゾルバを使用することについて少し心配しています。これは、完全に同期化された(同時に複数のスレッドからアクセスできる)依存性リゾルバと同時に多くの同時プラグインを処理するのに十分なパフォーマンスを必要とするためです。それについての考えは? –

+1

ええ、あなたは正しいですが、他の方法がないので、私はLazy <> :)を使って私が作成した要点を確認します。https://gist.github.com/msusur/e34be94cbceac20ea364でも、セットアップメソッドを分離する必要があります単一の責任を適用するためにFactoryメソッドを他のクラスに適用します。 –

+0

すばらしい解決策!ありがとう! –

5

プラグインは、ユニットテストの悩みの種です:非プラグインのテスト

    • 問題を一時的には
  • を実行している忘れて
  • 簡単に無効にする方法プラグイン自体をテストする際の問題
    • モックするためにたくさんのプロセスにアタッチし、パイプライン、サービスプロバイダなど
    • 実行し、マルチスレッド

これは、プラグインをテストするための次のソリューションに私をリードしてきました:

  • プラグインのコンテキストをできるだけ早く取り除き、必要なすべてのオブジェクトとサービスをすぐに抽出します。
  • ユニットテストをフックするためのExecutePluginメソッドを作成し、プラグインコンテキストからオブジェクトを抽出した後すぐにこのメソッドを呼び出します。
  • 可能な限り多くのコードをビジネスレイヤにプッシュします。

これは(これは簡単にするために拡張メソッドを頻繁に使用して)次のようになり、プラグインのような結果になります。これが行われる

public void Execute(IServiceProvider provider) 
{ 
    var context = provider.GetContext(); 
    var service = provider.GetService(context); 
    var target = GetTarget<Contact>(context); 
    if (target == null || !target.ContainsAllNonNull(c => new 
     { 
      c.FirstName, 
      c.LastName, 
     })) 
    { 
     // Entity is of the wrong type, or doesn't contain all of the required attributes 
     return; 
    } 

    ExecutePlugin(service, target); 
} 

public void ExecutePlugin(IOrganizationService service, Contact target){ 
    // Logic Goes Here 
} 

たら、ユニットに必要な唯一のものはExceutePluginをテスト必要な呼び出しを模倣し、ユニットテストを完了したあなたのIOrganizationServiceです。私はExecuteメソッドをテストするユニットにも気にしません。それがうまくいくか、またはCRM内から最初の使用時にチャウを吹き飛ばすことはありません。

+0

CRMのテストに関するこの素晴らしいガイドラインをお寄せいただきありがとうございます!私はまだ依存性注入について疑問に思っていますが、あなたはそれについて何か知っていますか? –

+0

@jrosseelこれはユニットテストのためのものだと思いますか?どのような依存関係をモック/スタブしたいのですか? – Daryl