【问题标题】:How to refactor method to replace OrganizationServiceProxy with IOrganizationService如何重构方法以用 IOrganizationService 替换 OrganizationServiceProxy
【发布时间】:2023-03-15 12:20:02
【问题描述】:

我正在尝试重构我的代码,以便我可以使用 fakexrmeasy 进行单元测试。

作为提到here 的建议重构的一部分,我尝试将 IOrganizationService 传递到我的所有类和方法中。但是,我的一些类使用了 IOrganizationService 没有的变量和方法,例如 Timeout。我正在尝试找到一种方法来重构以使用 IOrganizationService 而不会丢失功能。

这是重构前的样子。

class testClass () {

    public void testMethod(OrganizationServiceProxy service) {
        service.Timeout = new TimeSpan(0, 15, 0);
    }

}

这是在重构之后。 我尝试将 IOrganizationService 强制转换为 OrganizationServiceProxy,但伪造的服务上下文无法处理此强制转换。抛出异常。

class testClass () {

    public void testMethod(IOrganizationService service) {
        var serviceProxy = (OrganizationServiceProxy) service; //This breaks when given a fake context
        service.Timeout = new TimeSpan(0, 15, 0);
    }

}

我已尝试使用 IOrganizationServiceFactory,正如 this post 中所建议的那样。问题是 factory.CreateOrganizationService() 生成的是 IOrganizationService,而不是 OrganizationServiceProxy。

如何在不丢失功能的情况下重构以使用 IOrganizationService 而不是 OrganizationServiceProxy?我猜我可能不得不以某种方式将 IOrganizationService 实现为 OrganizationServiceProxy。

【问题讨论】:

    标签: c# dynamics-crm crm fakexrmeasy


    【解决方案1】:

    这样的事情可行吗?

    public class OrganizationServiceProxy : IServiceProxy
      {
        public int SomeProp
        {
          get
          {
            return 1;
          }
    
          set
          {
          }
        }
    
        public TimeSpan Timeout
        {
          get
          {
            return new TimeSpan();
          }
    
          set
          {
          }
        }
    
        public void SomeMethod()
        {
        }
      }
      public interface IServiceProxy : IOrganizationService
      {
        TimeSpan Timeout { get; set; }
      }
    
      public interface IOrganizationService
      {
        void SomeMethod();
        int SomeProp { get; set; }
      }
    

    由于 OrganizationServiceProxy 实现了 IServiceProxy(而后者又实现了 IOrganizationService),您可以检查您传入的对象是否实现了 IServiceProxy 接口并在 if 中执行您的工作。

    private void testMethod(IOrganizationService someService)
    {
       if(someService is IServiceProxy)
       {
         IServiceProxy tempProxy = someService as IServiceProxy;
         tempProxy.Timeout = new TimeSpan();
       }
    }
    

    【讨论】:

      【解决方案2】:

      我不确定这是否会有所帮助,但这是我使用的

      CrmServiceClient c = new CrmServiceClient(connectionstring); //various parameters available
      (OrganizationServiceProxy) service = c.OrganizationWebProxyClient ?? c.OrganizationServiceProxy;
      

      【讨论】:

        【解决方案3】:

        我认为有一个简单的解决方案 - 如果您不需要模拟 OrganizationServiceProxy 上的方法 - 只需忽略单元测试上下文中的那些。

        I.E.而不是

        // This breaks when given a fake context
        var serviceProxy = (OrganizationServiceProxy) service;
        serviceProxy.Timeout = new TimeSpan(0, 15, 0);
        

        var serviceProxy = service as (OrganizationServiceProxy);
        // The serviceProxy is null so it is ignored when given a fake context
        if (serviceProxy != null)
        {
           serviceProxy.Timeout = new TimeSpan(0, 15, 0);
        }
        

        【讨论】:

          【解决方案4】:

          两种选择:

          1) 为简单起见,重构您的代码,使其仅引用 IOrganizationService,并且仅在您的测试中使用该代码,并且不测试 TimeOut 位(超出重构函数的范围)

          2) 如果确实需要对 Timeout 属性进行单元测试,请模拟您自己的 OrganizationServiceContext 类,并将 FakeXrmEasy (IOrganizationService) 生成的模拟服务传递给 OrganizationServiceProxy 的构造函数。以下是所有可用构造函数的列表:

          https://docs.microsoft.com/en-us/dotnet/api/microsoft.xrm.sdk.client.organizationserviceproxy.-ctor?view=dynamics-general-ce-9

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2023-03-22
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多