c# - 包装第 3 方类 c# 的最佳方法是什么

标签 c# .net dependencies code-injection

<分区>

我从依赖注入(inject)开始,很难阻止一些第三方库类。例如,我的项目中有 EPPlus 库,它有不实现接口(interface)的 ExcelRange 类。由于我正在使用这个库,我发现我的代码是明确依赖的,无法正确地对代码的某些部分进行单元测试。

所以我的问题是什么是对第 3 方库类使用依赖注入(inject)的好方法。

最佳答案

对于这种情况,我的解决方案是创建另一个类和接口(interface)作为第三方库的包装器。在您的包装器中,创建与您在第三方库中使用的名称相同的函数。只创建那些对您的代码有值(value)的函数,如果您需要其他函数,请一点一点地添加到您的包装器中。现在,出于测试目的,您可以在不使用第三方库的情况下模拟/ stub 您的包装器接口(interface)。使用您的包装器注入(inject)到需要此服务的其他类。

您可以从简单的代码开始,然后随着知识的增长扩展它:

public interface IWrapperService
{
    Method(Dto model);

    Dto MethodProcess(Dto model);
}

public class WrapperService : IWrapperService
{
    private readonly ThirdPartyLib _thirdPartyLib;

    public WrapperService(ThirdPartyLib thirdPartyLib)
    {
        _thirdPartyLib = thirdPartyLib;
    }

    // Create your model - Dto
    // Dto will help you in your logic process
    // 
    public void Method(Dto model)
    {   
        //extract some properties in you model that only needed in your third party library 
        _thirdPartyLib.Method(parameter needed);
    }

    public Dto MethodProcess(Dto model)
    {   
        //extract some properties in you model that only needed in your third party library 
        ThirdPartyReturn value = _thirdPartyLib.MethodProcess(parameter needed);

        // Do the mapping
        var model = new Dto 
        {
            property1 = value.property1 // Do the necessary convertion if needed.
            .
            .
        }

        return model;
    }
    .
    .
    .
}

public interface IOtherClass 
{
  ...
}

public class OtherClass : IOtherClass 
{
   private readonly IWrapperService _wrapperService;

   public void OtherClass(IWrapperService wrapperService)
   {
        _wrapperService= wrapperService;
   }
   .
   .
}

对于依赖注入(inject),您可以使用 Microsoft unity .它将为您的依赖做出惊人的工作。你可以像这样使用它:

var unity = new UnityContainer();

// This is how you will inject your ThirdPartyLib
// You can also do it this way - unity.RegisterType<ThirdPartyLib>() but of course we need to limit the usage of your ThirdPartyLib in 
// our wrapper. We will not allowing directly access to Third Party Lib rather than wrapperService.

unity.RegisterType<IWrapperService, WrapperService>(new InjectionConstructor(new ThirdPartyLib()));
unity.RegisterType<IOtherClass, OtherClass>();

我同意@Alexei Levenkov 的观点,您需要阅读一些关于四人帮 (GOF) 的内容来改进此示例。以我的示例为起点。

包装您的第三方库可为您带来以下优势:

  • 它消除了对第三方库的分散和直接使用。
  • 它将一些复杂性封装在您的第三方库中。
  • 通过包装器可以轻松跟踪和维护第三方库。
  • 现在通过使用包装器可以轻松进行单元测试。
  • 依赖注入(inject)将帮助您解决横切问题。

一些缺点:

  • 乏味且引入了重复的方法。
  • 介绍新模型的创建 - 视情况而定,如果您的第三方库只询问(int、字符串、 bool 值)等少数参数,请不要为模型操心。
  • 一开始应用设计模式可能会很困难,但从长远来看,它会给您带来优势。

关于c# - 包装第 3 方类 c# 的最佳方法是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31530165/

相关文章:

c# - 在 silverlight 应用程序中显示 HTML

c# - 填写表格并打印文档

java - 在 Java 中查找 eclipse/jdt 的 jar 依赖项

c# - 如何在选项工具提示的下拉列表中使用对象属性?

c# - 如何将快照文件转换为任何其他格式?

c# - struct tostring() 方法重定向到抽象类 ValueType

c# - 是否可以限制或限制可从 DLL 执行的 C# 代码的范围?

android firebase 在 gradle 中添加依赖项时显示错误

eclipse - m2eclipse中的依赖问题

c# - 如何在web服务和手机之间进行身份验证?