包装第 3 方 class c# 的最佳方法是什么
What is best way to wrap 3rd party class c#
我从依赖注入开始,很难阻止某些第三方库 classes。例如,我的项目中有 EPPlus 库,它有 ExcelRange class,它没有实现接口。因为我正在使用这个库,所以我发现我的代码是明确依赖的,无法正确地对代码的某些部分进行单元测试。
所以我的问题是什么是对第 3 方库 classes 使用依赖注入的好方法。
我对这种情况的解决方案是创建另一个 class 和接口作为第三方库的包装器。在您的包装器中,创建与您在第三方库中使用的名称相同的函数。只创建那些对您的代码有价值的函数,如果您需要其他函数,请一点一点地添加到您的包装器中。现在,出于测试目的,您可以 mock/stub 您的包装器接口而无需使用第三方库。使用您的包装器注入到其他需要此服务的 class。
您可以从简单的代码开始,然后随着知识的增长扩展它:
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;
}
.
.
}
对于依赖注入,您可以使用 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) 的内容来改进此示例。以我的示例为起点。
包装第三方库可为您带来以下优势:
- 它消除了对第三方库的分散和直接使用。
- 它在您的第三方库中封装了一些复杂性。
- 通过包装器很容易跟踪和维护第三方库。
- 现在通过使用包装器可以轻松进行单元测试。
- 依赖注入将帮助您解决横切问题。
缺点很少:
- 繁琐且引入重复方法。
- 介绍新模型的创建 - 这取决于,如果您的第三方库只询问(int、字符串、布尔值)等几个参数,请不要为模型烦恼。
- 一开始应用设计模式可能会很困难,但它会给你带来长期优势 运行。
我从依赖注入开始,很难阻止某些第三方库 classes。例如,我的项目中有 EPPlus 库,它有 ExcelRange class,它没有实现接口。因为我正在使用这个库,所以我发现我的代码是明确依赖的,无法正确地对代码的某些部分进行单元测试。
所以我的问题是什么是对第 3 方库 classes 使用依赖注入的好方法。
我对这种情况的解决方案是创建另一个 class 和接口作为第三方库的包装器。在您的包装器中,创建与您在第三方库中使用的名称相同的函数。只创建那些对您的代码有价值的函数,如果您需要其他函数,请一点一点地添加到您的包装器中。现在,出于测试目的,您可以 mock/stub 您的包装器接口而无需使用第三方库。使用您的包装器注入到其他需要此服务的 class。
您可以从简单的代码开始,然后随着知识的增长扩展它:
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;
}
.
.
}
对于依赖注入,您可以使用 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) 的内容来改进此示例。以我的示例为起点。
包装第三方库可为您带来以下优势:
- 它消除了对第三方库的分散和直接使用。
- 它在您的第三方库中封装了一些复杂性。
- 通过包装器很容易跟踪和维护第三方库。
- 现在通过使用包装器可以轻松进行单元测试。
- 依赖注入将帮助您解决横切问题。
缺点很少:
- 繁琐且引入重复方法。
- 介绍新模型的创建 - 这取决于,如果您的第三方库只询问(int、字符串、布尔值)等几个参数,请不要为模型烦恼。
- 一开始应用设计模式可能会很困难,但它会给你带来长期优势 运行。