I have a problem using DI with constructor properties. I am building a PDFBuilder
based on my IPDFBuilder
.
public interface IPDFBuilder
{
string templatefilepath { get; }
string templatefilename { get; }
Dictionary<string, string> dict { get; }
void CreatePDF();
}
public class PDFBuilder : IPDFBuilder
{
public string templatefilename { get; private set; }
public string templatefilepath { get; private set; }
public Dictionary<string, string> dict { get; private set; }
public PDFBuilder(string templatefilename, string templatefilepath, Dictionary<string, string> dict)
{
this.templatefilename = templatefilename;
this.templatefilepath = templatefilepath;
this.dict = dict;
}
public void CreatePDF() {
//Do something
}
}
This PDFBuilder
can and will be used in multiple controllers, for example:
public class KeuringController : Controller
{
private IPDFBuilder _PDFBuilder;
public KeuringController(IPDFBuilder pdfBuilder)
{
_PDFBuilder = pdfBuilder;
}
//Action methods that use `PDFBuilder` below...
}
However, I can't set the properties of PDFBuilder
in the startup class (where DI registration is beeing done) because different controllers will use different values for the properties of the PDFBuilder
class. 1 simple solution would be to just make the setters of the properties public so in an action method I can set the values and then call CreatePDF()
. However this doesn't feel right. Another simple solution would be to remove the class properties and just pass the 3 properties of PDFBuilder
as method properties to the CreatePDF
method like this:
public void CreatePDF(string templatefilename, string templatefilepath, Dictionary<string, string> dict) {
//Do something
}
But now let's say that my PDFBuilder
whould have 10 methods which all need these 3 properties. Then this is not the correct solution right?
What would be the correct solution then? I have encountered this problem multiple times with different classes/interfaces implementations and would like to have some help with designing in these situations.
You are injecting runtime data into your component's constructor, which is a bad thing. The solution is to move those runtime values out of the constructor into the CreatePDF
method:
public interface IPDFBuilder
{
void CreatePDF(string templatefilepath, string templatefilename,
Dictionary<string, string> dict);
}