Reputation: 490
I'm implementing dependency injection with Autofac. I have trouble using the correct instance of an object that I pass into the component constructor.
My intention here is for the Autofac to create both ReportFileGenerator and ReportDefinition and then change the values of ReportDefinition by the post action in the controller before creating the ReportFileGenerator so the updated value can be passed as its parameter.
I have a ReportController:
public class ReportController
{
private readonly IReportFileGenerator _reportFileGenerator;
private IReportDefinition _reportDefinition;
public ReportController(
IReportFileGenerator reportFileGenerator,
IReportDefinition reportDefinition
{
_reportFileGenerator = reportFileGenerator;
_reportDefinition = reportDefinition;
}
(...)
[HttpPost]
public ActionResult Report(ReportViewModel viewModel)
{
_reportDefinition = viewModel.ReportDefinition
return _reportFileGenerator.GenerateReportFile();
}
}
ReportFileGenerator
public class ReportFileGenerator : IReportFileGenerator
{
private readonly IReportDefinition _reportDefinition;
public ReportFileGenerator(
IReportDefinition reportDefinition)
{
_reportDefinition = reportDefinition
}
public FileContentResult GenerateReportFile()
{
[some logic to generate file result using reportDefinition]
}
}
and finally my registrations:
builder.RegisterType<ReportFileGenerator>()
.As<IReportFileGenerator>()
.InstancePerRequest();
builder.RegisterType<ReportDefinition>()
.As<IReportDefinition>()
.InstancePerRequest();
The problem is the ReportDefinition that is being passed into the ReportFileGenerator does not have values assigned in the controller action (it is just a brand new instance with default values).
Upvotes: 1
Views: 418
Reputation: 247008
Review the current design. It appears that ReportDefinition
should be used as an explicit dependency for IReportFileGenerator.GenerateReportFile()
public interface IReportFileGenerator {
FileContentResult GenerateReportFile(ReportDefinition reportDefinition);
}
You appear to be using ReportDefinition
more like a model, than a service. I see no need to be injecting it via constructor.
public class ReportFileGenerator : IReportFileGenerator {
public FileContentResult GenerateReportFile(ReportDefinition reportDefinition) {
//[some logic to generate file result using reportDefinition]
}
}
Which would allow the controller to invoke the IReportFileGenerator
as intended
public class ReportController {
private readonly IReportFileGenerator reportFileGenerator;
public ReportController( IReportFileGenerator reportFileGenerator) {
this.reportFileGenerator = reportFileGenerator;
}
//(...)
[HttpPost]
public ActionResult Report(ReportViewModel viewModel) {
ReportDefinition reportDefinition = viewModel.ReportDefinition;
return reportFileGenerator.GenerateReportFile(reportDefinition);
}
}
In your original design, you appear to misunderstand how to use DI in that situation.
Upvotes: 2