在下面的IoC标准的C#代码,应该每一个IO操作的类处理IO操作中被包裹?例如,我使用File.Exists和Directory.Create所有的地方 - 我应该有一个类暴露出这两个函数和整个应用程序使用,以创建一个抽象层的每一个文件操作?
,我可以使用什么Path.Combine,或Path.DirectorySeparatorChar直接或者我应该还他们周围创建包装?
返回文件信息变得更加棘手一点,我可以有一个函数返回文件大小,但如果我需要访问多个属性,然后我返回FileInfo对象 - 不应该只是我宁可在代码初始化FileInfo的,而不是包装的它?
找到了答案。
不换IO调用意味着你不能单元测试类,因为它会改变,而不是在沙箱中运行真正的文件。
这意味着,是的,每次通话都必须包。幸运的是,System.IO.Abstraction提供了这样的抽象所以只要将其插入该项目并使用它。
然后,我可以创造IFileSystemExt揭露IO操作的公共集,如“确保存在路径的文件夹”和“如果存在删除文件”。
不能,也不应该不是普遍状态是什么一定要与决不能依赖注入(DI)的背景下完成的。这实际上取决于一个试图解决问题的类型。如果只关注可测性,然后隐藏任何具有不确定性,或有副作用,可能是可取的。
但是请注意,这不包括Path.Combine
或Path.DirectorySeparatorChar
。这些成员是,IIRC,完全确定性;当你调用他们,他们不会访问文件系统。
对DI的常用方法,但是,是应用Dependency Inversion Principle(DIP)。根据这一原则,客户端代码决定,并控制它使用多态的API的形状。一旦客户端代码已经冲出接口,它需要你去找出如何实现这些接口。
许多人试图解决对Windows文件系统的可测试性的东西,如System.IO.Abstractions,但完全违反了DIP。与其让客户定义的接口的形状,它可以让一个实现定义API。这是一个leaky abstraction,如果它是一个抽象的。