我开始与依赖注入,并有困难的时候obestcting一些第三方库类。例如我在我的项目中有EPPlus库,它有一个没有实现接口的ExcelRange类。由于我正在使用这个库,我发现我的代码显式依赖,无法正确地单元测试代码的某些部分。什么是最好的方式来包装第三方类c#
所以我的问题是什么是与第三方库类使用依赖注入的好方法。
我开始与依赖注入,并有困难的时候obestcting一些第三方库类。例如我在我的项目中有EPPlus库,它有一个没有实现接口的ExcelRange类。由于我正在使用这个库,我发现我的代码显式依赖,无法正确地单元测试代码的某些部分。什么是最好的方式来包装第三方类c#
所以我的问题是什么是与第三方库类使用依赖注入的好方法。
我对这种情况的解决方法是创建另一个类和接口作为包装到您的第三方库。在包装中,创建与您在第三方库中使用的名称相同的函数。只创建那些对代码有价值的函数,如果你需要其他函数将它们添加到你的包装中,则一点一点地创建这些函数。现在,出于测试目的,您可以模拟/存根您的包装界面,而无需使用第三方库。使用你的包装器注入其他需要此服务的类。
你可以用简单的代码开始并扩大它作为你的知识增长:
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)的冈一些东西来改善这个样品。以我的样本为出发点。
包装一下你的第三方库为您提供了以下优点:
一些缺点:
谢谢你的回应。这是一个相当大的图书馆。如果没有别的办法,我想我已经花时间去做了。你能举个例子吗? – Farukh
有一些书讨论解决像GoF(又名设计模式)这样的问题的方法和“有效地使用遗留代码”的方法。除了广泛涉及您的问题之外,这两本书都是非常有用的优秀阅读材料。 –