Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 包装第三方c类的最佳方式是什么#_C#_.net_Dependencies_Code Injection - Fatal编程技术网

C# 包装第三方c类的最佳方式是什么#

C# 包装第三方c类的最佳方式是什么#,c#,.net,dependencies,code-injection,C#,.net,Dependencies,Code Injection,我从依赖注入开始,很难观察到一些第三方库类。例如,我的项目中有一个EPPlus库,它有一个ExcelRange类,它没有实现接口。由于我使用这个库,我发现我的代码是显式依赖的,无法正确地对代码的某些部分进行单元测试 所以我的问题是,什么是对第三方库类使用依赖注入的好方法 我的解决方案是创建另一个类和接口作为第三方库的包装器。在包装器中,创建与您在第三方库中使用的相同名称的函数。只创建那些对代码有价值的函数,如果您需要其他函数,请一点一点地将其添加到包装器中。现在,出于测试目的,您可以在不使用第三

我从依赖注入开始,很难观察到一些第三方库类。例如,我的项目中有一个EPPlus库,它有一个ExcelRange类,它没有实现接口。由于我使用这个库,我发现我的代码是显式依赖的,无法正确地对代码的某些部分进行单元测试


所以我的问题是,什么是对第三方库类使用依赖注入的好方法

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

您可以从简单的代码开始,并随着知识的增长进行扩展:

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;
   }
   .
   .
}
对于依赖项注入,您可以使用。它将为你的依赖性做一件了不起的工作。您可以这样使用它:

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>();
var unity=new UnityContainer();
//这就是你注射第三方B的方法
//您也可以这样做-unity.RegisterType(),但我们当然需要限制第三方数据库在中的使用
//我们的包装纸。我们将不允许直接访问第三方Lib而不是wrapperService。
RegisterType(新的InjectionConstructor(新的ThirdPartyLib());
unity.RegisterType();
我同意@Alexei Levenkov的观点,你需要阅读一些关于四人帮(GOF)的资料来改进这个示例。以我的样品为起点

包装您的第三方库具有以下优点:

  • 它消除了对第三方库的分散和直接使用
  • 它在您的第三方库中封装了一些复杂性
  • 通过包装器很容易跟踪和维护第三方库
  • 现在,通过使用包装器,单元测试将变得很容易
  • 依赖注入将帮助您解决跨领域问题
几个缺点:

  • 单调乏味,引入重复的方法
  • 引入新模型的创建——这取决于您的第三方库是否只要求几个参数,如(int、string、boolean),而不必为模型费心
  • 一开始应用设计模式可能很困难,但从长远来看,它会给您带来优势

感谢您的回复。这是一个相当大的库,需要一对一地包装。如果没有别的办法,我想我已经花时间做了。你能举个例子吗?有一些书讨论解决这个问题的方法,比如GoF(又名设计模式)和“有效地使用遗留代码”。这两本书都是很好的阅读材料,除了广泛地涵盖你的问题外,总体上也是很有用的。