我有以下接口和类:
public interface ILoggingService { ... }
public class LoggingService {
public LoggingService(ILoggingRepository loggingRepository) { ... }
...
}
public interface ILoggingRepository { ... }
public class DatabaseLoggingRepository {
public DatabaseLoggingRepository(string ConnectionString) { ... }
...
}
public class FileLoggingRepository {
public FileLoggingRepository(string LogFilePath) { ... }
...
}
我正在重构我的软件以使用Unity IoC框架,并且正在寻找一种方法将特定配置传递给每个ILoggingRepository实现。
我认为最好的方法是将DatabaseLoggingRepository和FileLoggingRepository的构造函数更改为根本没有参数,并让它们由某个配置文件配置。但是,由于我的验收测试,我需要一种简单的方法来在运行测试时覆盖这些设置。
我是否在正确的轨道上,如果我在,我应该使用哪些配置文件?也欢迎其他方式。
答案 0 :(得分:2)
我们决定创建一个类,在您的情况下它将是LoggingConfiguration
,并将其传递给存储库的constructo。如果您使用Unity解析它将使用Activator
实例化此类,wuthout必须注册它。但是,在测试中,您只需更新派生配置类的新实例,从而提供不同的值。
有意义吗?我应该澄清一下吗?
更新:我决定提供一些额外的说明。因此,您已经有两个实现,现在您希望每个配置都查询其正确的配置设置。
我会将ILoggingRepository
的构造函数扩展为:
public ILoggingRepository(ILoggingConfigurationProvider confProvider);
然后,您可以为正常操作创建一个具有两个属性的实现:
public LoggingConfigurationProvider : ILoggingConfigurationProvider {
public LoggingConfigurationProvider() {
// load both values from configuration file
}
public string LogPath { get; set; }
public string ConnectionString { get; set; }
}
当您通过正常的IoC操作实例化您的类时,这将由容器解决,您将从conf文件加载配置选项。但是,如果您想进行单元测试:
1)创建一个新的“模拟”实现
public class MockLoggingConfigurationProvider : ILoggingConfigurationProvider {
public MockLoggingConfigurationProvider() {
// set both values to a test value
}
public string LogPath { get; set; }
public string ConnectionString { get; set; }
}
现在您可以使用构造函数创建存储库:
new LoggingRepository(new MockLoggingConfigurationProvider());
或者如果您希望使用整个IoC机制,您只需(在设置容器时)注册该接口的实现。因为单元测试是分开的,所以你不共享注册吗?所以这应该给你你需要的东西,能够根据他们作为单位测试执行的天气来改变这些设置。
在现实生活中,我甚至不愿意这样做,只需创建一个模拟日志存储库并将其写入其他地方。除非您要将存储库测试到测试数据库/文件。在这种情况下,我会按照规定行事。
希望它有所帮助。
答案 1 :(得分:0)
由于设计建议不强制IoC处理配置内容。每个记录器应该在实现时按照自己喜欢的方式管理配置。 IoC应该只注入记录器。对于单元/集成测试,在这两种情况下,您都应该能够为记录器提供配置,例如使用log4net我用于在api的测试启动中配置记录子系统,并且我创建了一个appender在控制台上写的只是一个人。您无法通过IoC进行Insolate配置,因为每个可能的日志记录系统都不需要共享配置部分的合同。