Phi*_*ler 16 extension-methods dependencies inversion-of-control testability c#-3.0
所有,
想要对此有所了解.最近,我在设计/开发时越来越多地成为"纯粹的"DI/IOC原则的订户.其中一部分(很大一部分)涉及确保我的类之间几乎没有耦合,并且它们的依赖关系是通过构造函数解决的(当然还有其他方法来管理它,但你明白了).
我的基本前提是扩展方法违反了DI/IOC的原则.
我创建了以下扩展方法,以确保插入到数据库表中的字符串被截断为正确的大小:
public static class StringExtensions
{
public static string TruncateToSize(this string input, int maxLength)
{
int lengthToUse = maxLength;
if (input.Length < maxLength)
{
lengthToUse = input.Length;
}
return input.Substring(0, lengthToUse);
}
}
Run Code Online (Sandbox Code Playgroud)
然后我可以从另一个类中调用我的字符串,如下所示:
string myString = "myValue.TruncateThisPartPlease.";
myString.TruncateToSize(8);
Run Code Online (Sandbox Code Playgroud)
不使用扩展方法对此进行公平的翻译将是:
string myString = "myValue.TruncateThisPartPlease.";
StaticStringUtil.TruncateToSize(myString, 8);
Run Code Online (Sandbox Code Playgroud)
使用上述任一示例的任何类都无法独立于包含TruncateToSize方法的类(除了TypeMock)进行测试.如果我没有使用扩展方法,并且我不想创建静态依赖项,它看起来更像:
string myString = "myValue.TruncateThisPartPlease.";
_stringUtil.TruncateToSize(myString, 8);
Run Code Online (Sandbox Code Playgroud)
在最后一个示例中,_stringUtil依赖项将通过构造函数解析,并且可以测试该类,而不依赖于实际的TruncateToSize方法的类(可以很容易地模拟).
从我的角度来看,前两个示例依赖于静态依赖(一个显式,一个隐藏),而第二个反转依赖性并提供减少的耦合和更好的可测试性.
那么扩展方法的使用是否与DI/IOC原则相冲突?如果您是IOC方法的订阅者,您是否避免使用扩展方法?
Jon*_*eet 18
我认为这很好 - 因为它不像TruncateToSize是一个现实可替换的组件.这是一种只需要做一件事的方法.
您不需要能够模拟所有内容 - 只是破坏单元测试(文件访问等)的服务或者您想要根据真正依赖性测试的服务.如果您使用它来执行身份验证或类似的东西,那将是一个非常不同的问题...但只是做一个完全没有可配置性,不同的实现选项等的直接字符串操作 - 没有必要将它视为依赖在正常意义上.
换句话说:如果TruncateToSize是真正的成员String,你甚至会三思而后行吗?你是否试图模拟整数运算,引入IInt32Adder等?当然不是.这是一样的,只是你碰巧提供了实现.单元测试出来TruncateToSize并且不用担心.
Lor*_*nVS 17
我知道你来自哪里,但是,如果你试图嘲笑扩展方法的功能,我相信你错误地使用它们.应该使用扩展方法来执行一个在没有它们的情况下语法上很不方便的任务.你的TruncateToLength就是一个很好的例子.
测试TruncateToLength不会涉及模拟它,它只需要创建一些字符串并测试该方法实际返回正确的值.
另一方面,如果您的数据层中的代码包含在访问数据存储的扩展方法中,那么是的,您遇到了问题,测试将成为一个问题.
我通常只使用扩展方法来为小而简单的操作提供语法糖.
| 归档时间: |
|
| 查看次数: |
1788 次 |
| 最近记录: |