MS Dynamics CRM中的依赖注入

Jen*_*eel 9 c# dynamics-crm dynamics-crm-2011

我目前正在开始使用插件扩展Microsoft Dynamics CRM.

是否可以在这些插件中添加依赖注入(用于测试,松耦合等目的)?我在哪里可以注册我的IoC容器,以便它用于所有相同类型的插件?

Dar*_*ryl 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
}
Run Code Online (Sandbox Code Playgroud)

完成后,您需要进行单元测试的唯一方法就是ExceutePlugin自己IOrganizationService完成所需的调用并完成单元测试.我甚至不打扰单元测试Execute方法.它既可以工作,也可以不用,并且可以在CRM中首次使用.


Mer*_*sur 5

我们一直在尝试对Dynamics CRM应用程序进行单元测试并应用依赖注入.不幸的是,随着Microsoft支持和顾问的确认,没有受支持的方式来实现它.您可以将所有插件业务逻辑转移到另一个业务类,并应用依赖注入或停止考虑它.

如果您选择使用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);
}
Run Code Online (Sandbox Code Playgroud)

我真的不明白为什么微软不会简单地让我们将一些组件注册到他们在内部使用的IServiceProvider实现中.

PS.由于您的SuperPlugin类是IPlugin,您可能忘记在子类上编写接口实现.但是我们在官方Dynamics CRM SDK附带的插件注册工具上遇到了一些错误.因此,如果您遇到同样的问题,您还应该按如下方式实现插件,

public class MyPlugin : SuperPlugin, IPlugin{
  public abstract void OnExecution(IDependencyResolver resolver){};
}
Run Code Online (Sandbox Code Playgroud)

编辑:查看一个解释概念https://github.com/nakahparis/DIForCRM的小例子