'How to abstract away an implementation that requires runtime data during its construction?

I have some trouble with dependency injection. Assume we have the following code:

[Snippet 1]

public class FooBar 
{ 
  public FooBar (){}

  public void DoSomething(string param1, int param2)
  {
    var reader = new Reader(param1, param2)
    parser.Read();
  }  
}

I don' t want anymore the class FooBar to use the new operator. I will have two kinds of parsers ExcelParser and XmlParser. They both implement an interface IParser. Then depending on the configuration I will add one Parser or another, i.e., in Program.cs I will have something like

if (Environment == something) {
  services.AddSingleton<IParser,ExcelParser>();
} else {
  serrvices.AddSingleton<IParser,XmlParser();
}

The code will be something like this

My question is: In snippet 1, to instantiate the Paser we passed param1 and param2. In snippet 2, How will the DI container get those parameters to create an instance? Something is missing in my understanding of DI.



Solution 1:[1]

Change the IParser interface to:

public interface IParser
{
    void Execute(string param1, string param2);
}

This way, FooBar can pass on the parameters without having to instantiate the parser:

public class FooBar 
{ 
  private readonly IParser _parser;
  
  public FooBar(IParser parser)
  {
      _parser = parser;
  }

  public void DoSomething(string param1, int param2)
  {
      _parser.Execute(param1, param2);
  } 
}

More details on why and how can be found in this article: Dependency Injection Code Smell: Injecting runtime data into components.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Steven