理论问题:最佳实践不是在构造函数中做任何工作,不是新事物,除了设置成员之外什么都不做。
在简单示例(依赖注入)中,需要将文件从磁盘加载到成员以使类正常工作,我应该在哪里进行"工作"?在一些初始化函数中,我需要记住调用?
例如:
XDocument.Load(someFilePath) ;
答案 0 :(得分:2)
最佳做法是不要在注入构造函数中做任何工作,因为Mark Seemann清楚地解释了here。因此,如果您需要从磁盘加载文件,您应该在启动期间(如果可能)执行此操作,或者推迟创建并在构建对象图之后执行此操作。这通常不是一个讨厌的解决方法,而Lazy是推迟创建事物的一个很好的机制。例如:
class ApplicationConfiguration
{
private readonly Lazy<XDocument> configFile;
public ApplicationConfiguration(Lazy<XDocument> configFile) {
this.configFile = configFile;
}
public T GetValue<T>(string key) {
return (T)this.configFile.Value.Root.Find(key).Value;
}
}
但有关Lazy<T>
的警告。虽然它可以(而且应该)用于推迟事物的创建,但请确保不要将其作为漏洞抽象滥用。例如,不要在许多类中注入相同的Lazy<T>
依赖项。例如,假设您有一个ILogger
抽象,并且您获得的创建时间非常昂贵。你可能很想开始在所有地方注入Lazy<ILogger>
,但是现在你正在泄漏实现细节,因为这个logger创建成本很高的事实是一个实现细节,但是现在{{1}的所有消费者知道这一点,你只需要不小心注入ILogger
一次就可以打破这种优化。
因此,创建一个实现ILogger
并依赖于ILogger
的代理类,并将此代理注入所有使用者。这样所有消费者都可以依赖于Lazy<ILogger>
,而无需知道记录器的创建被延迟。