2014-01-15 93 views
8

我目前正在開始使用插件對Microsoft Dynamics CRM進行擴展。MS Dynamics CRM中的依賴注入

是否可以向這些插件添加依賴注入(用於測試,鬆耦合等目的)?我可以在哪裏註冊我的IoC容器,以便它用於相同類型的所有插件?

+0

您可以投票支持對HTTPS此功能: //ideas.dynamics.com/ideas/dynamics-crm/814208 –

回答

5

我們一直在嘗試對我們的Dynamics CRM應用程序進行單元測試並應用依賴注入。不幸的是,由於微軟的支持和顧問得到了確認,所以沒有支持的方式來做到這一點。您可以將所有插件業務邏輯轉移到另一個業務類,並應用依賴注入或停止考慮它。

如果您選擇使用Dynamics CRM進行反擊,則需要在插件超類上定義一個靜態字段,該字段將成爲您的DI容器。具體如下,

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); 
} 

我真的不明白,爲什麼微軟不只是讓我們註冊了一些組件,它們在內部使用的IServiceProvider執行。

Ps。由於你的SuperPlugin類是一個IPlugin,你可能會忘記在子類上編寫接口實現。但是我們遇到了官方Dynamics CRM SDK附帶的插件註冊工具中的一些錯誤。所以,如果你可能有同樣的問題,你也應該實現你的插件如下,

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

編輯:看到一個小例子,解釋概念https://github.com/nakahparis/DIForCRM

+0

很好的解決方法。你將如何實例化依賴解析器?使用靜態類還是單例結構?我有點擔心使用靜態解析器,因爲您需要一個完全同步的依賴解析器(可以同時由多個線程訪問),同時性能足以處理多個併發插件。對此有何想法? –

+1

是的你是對的,但因爲沒有其他方式我更喜歡使用懶惰<> :)檢查我創建的要點,https://gist.github.com/msusur/e34be94cbceac20ea364,但你也需要分開安裝方法和工廠的方法,以適用於其他職責。 –

+0

偉大的解決方案!謝謝! –

5

插件在CRM是單元測試的禍根:

  • 與非插件測試問題
    • 沒有辦法暫時禁用
    • 容易忘記它正在運行
  • 測試插件本身的問題
    • 無法進行單元測試和重視處理
    • 很多模擬出,管道,服務提供商等
    • 運行多線程

這導致我到下面的解決方案用於測試的插件:

  • 儘快擺脫插件上下文,立即提取所需的所有對象和服務。
  • 創建一個掛鉤單元測試的方法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