使用 IoC 容器在运行时解决嵌套依赖关系的模式
我有一个类,用于协调数据文件包的准备、验证和清理例程。我正在努力寻找一种在使用 IoC 容器(本例中为 Ninject)时感觉正确的模式。我遇到的问题是,根据包中提供的内容,我可以使用多个验证类之一。以下是正在发生的事情的粗略想法:
public class PackageProcessor
{
private readonly ILog log;
public PackageProcessor(ILog log)
{
this.log = log;
}
public void Process(CustomerProfile profile, PackageType type, string path, bool validateOnly = false, bool offlineValidation = false)
{
// ...
// Uncompress package files (if compressed) or copy raw files to woroking folder
// Ensure working folder contains the required files for the package type
// Validate package data
foreach (var packageFile in packageConfiguration)
{
var timer = Stopwatch.StartNew();
var recordCount = 0UL;
var validator = DependencyResolver.Kernel.Get<RecordValidator>(metadata =>
metadata.Has("file") &&
String.Equals(metadata.Get<string>("file"), packageFile.Name, StringComparison.OrdinalIgnoreCase));
using (var reader = new CsvReader(new StreamReader(Path.Combine(workingFolder.FullName, packageFile.Name)), false))
{
while (reader.ReadNextRecord())
{
var recordResult = validator.IsValid(reader);
if(!recordResult.IsValid)
{
// LOG: record error messages
// Mark the job as failed
}
recordCount++;
}
}
// LOG: File appears to be valid. {0} records were found.
// LOG: File contains invalid records. {0} records were found, {1} were invalid.
timer.Stop();
log.Info(m => m(Strings.RecordsProcessed, recordCount, timer.Elapsed, (recordCount / timer.Elapsed.TotalSeconds)));
}
// Clean and output the data
}
}
如您所见,我需要动态解析验证类作为过程的一部分。在过去,我会创建一个工厂类来找到正确的验证器并返回它。我倾向于通过构造函数注入该工厂,但想将其放在那里,看看您是否可能遇到更好的方法来处理嵌套依赖项解析,而无需传递 IoC 容器引用。
(可能有 一个重复的问题,但如果我们问同样的事情,我仍在努力解决)
I have a class that coordinates preparation, validation, and cleansing routines for a package for data files. I am struggling to find a pattern that feels right when using an IoC container (Ninject in this case). The problem I am running into is that the depending on what is delivered in the package I could be using one of several validation classes. Here is a rough idea of what is going on:
public class PackageProcessor
{
private readonly ILog log;
public PackageProcessor(ILog log)
{
this.log = log;
}
public void Process(CustomerProfile profile, PackageType type, string path, bool validateOnly = false, bool offlineValidation = false)
{
// ...
// Uncompress package files (if compressed) or copy raw files to woroking folder
// Ensure working folder contains the required files for the package type
// Validate package data
foreach (var packageFile in packageConfiguration)
{
var timer = Stopwatch.StartNew();
var recordCount = 0UL;
var validator = DependencyResolver.Kernel.Get<RecordValidator>(metadata =>
metadata.Has("file") &&
String.Equals(metadata.Get<string>("file"), packageFile.Name, StringComparison.OrdinalIgnoreCase));
using (var reader = new CsvReader(new StreamReader(Path.Combine(workingFolder.FullName, packageFile.Name)), false))
{
while (reader.ReadNextRecord())
{
var recordResult = validator.IsValid(reader);
if(!recordResult.IsValid)
{
// LOG: record error messages
// Mark the job as failed
}
recordCount++;
}
}
// LOG: File appears to be valid. {0} records were found.
// LOG: File contains invalid records. {0} records were found, {1} were invalid.
timer.Stop();
log.Info(m => m(Strings.RecordsProcessed, recordCount, timer.Elapsed, (recordCount / timer.Elapsed.TotalSeconds)));
}
// Clean and output the data
}
}
As you can see I have a need to resolve the validation class dynamically as part of the process. In the past I would have created a Factory class to locate the proper validator and return it. I am leaning towards injecting that factory through the constructor but wanted to put it out there to see if there are any better approaches that you might have encountered for dealing with nested dependency resolution without having to pass around IoC container references.
(There might be a duplicate question, but I'm still trying to work through if we're asking the same thing)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
假设验证器和处理器是可重用的,我会采取完全不同的方法。我将在构造函数中注入所有 RecordValidators 并向其添加 CanHandle(??? packageFile) 方法,并在循环中选择匹配的方法,或者注入一个包含所有验证器的验证器选择器并从中获取它。
Assuming that the validators and the processor are reusable I'd take a completely other approach. I'd inject all the RecordValidators in the constructor and add a CanHandle(??? packageFile) method to them and select the matching one in the loop or alternatively inject a validator selector having all the validators and get it from this one.