[英]Dependency injection with runtime parameters in the constructor
我开始实现一个控制台应用程序并学习 DI 和 IOC。
所以我决定写两个 class
public class Reporter {
public readonly IDataExport exporter;
public readonly IService service;
Reporter(IService service, IDataExport export ) {
service = service;
exporter = exporter;
}
public void Run() {
var data = service.GetData();
exporter.Export(data);
}
}
出口商定义为
public class CsvExporter : IDataExport {
public readonly StreamWriter writter;
CsvExporter(StreamWriter writer) {
writer = writer;
}
//interface implementation
public async Task Export(IEnumerable<Person> data)
{
var formmatedData = FormartData(data)
await writer.WriteAsync(formattedData);
await writer.FlushAsync();
}
}
我的问题是,如果我必须使用需要编写 csv 并且文件名必须在运行时作为参数传递的 StreamWriter,我该如何处理 IOC
亲切的问候和感谢
解决这个问题的典型方法是使用工厂。 有很多方法可以构建它,这只是一个例子:
public interface IDataExportFactory{
IDataExport Create(Stream stream);
}
另一种选择是将参数移动到方法
public async Task Export(IEnumerable<Person> data, Stream stream)
对于这个相当简单的示例,两种选择都非常相似。 如果您有一个可以导出不同类型数据或做更多事情的大型界面,前者可能会更好。
我建议使用Stream
而不是StreamWriter
,因为前者更通用。
如果您需要导出器忽略导出目标,您可以注入一个已经具有 stream 的 CsvWriter 实例,或者有一些获取 stream 的方法。 但从问题中不清楚究竟应该由哪个组件负责创建 stream,或者是否所有出口商都应该能够写入 stream。
If you are using a an IoC container that supports method injection like autoface ( docs ) you can use it to inject the Stream
outside of the class scope, and then let some other class to be responsible for initiating the Stream
object:
var builder = new ContainerBuilder();
builder.RegisterType<WriterService>().As<IWriterService>();
builder.RegisterType<CsvExporter>()
.OnActivated(IActivatedEventArgs<CsvExporter> e) =>
{
var stream = e.Context.Resolve<IWriterService>(); --> runtime resolving!!
e.Instance.SetStream(stream);
});
并修改您的 class 以具有SetStream
方法:
public class CsvExporter : IDataExport {
private Stream _writter;
SetStream(Stream writer) {
this._writer = writer;
}
//interface implementation
public async Task Export(IEnumerable<Person> data)
{
var formmatedData = FormartData(data)
await this._writer.WriteAsync(formattedData);
await this._writer.FlushAsync();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.