Reputation: 13
Ok this is driving me crazy! I have a generic method in a generic class.
public interface IHandler<T> where T : class
{
T[] parseCSV(string InputFileName)
}
public class Handler<T> : IHandler<T> where T : class
{
public T[] parseCSV(string InputFileName)
{
if (File.Exists(InputFileName))
{
_inputFileName = InputFileName;
var Engine = new FileHelperEngine<T>();
return Engine.ReadFile(_inputFileName);
}
else
{
throw new IOException($"{InputFileName} not found!");
}
}
}
I have registered the generic in a IoC container as such:
container.RegisterType(typeof(IHandler<>), typeof(Handler<>));
Along with several mappers to parse files with the FileHelpers package
container.RegisterType<IMapper1, Mapper1>();
container.RegisterType<IMapper2, Mapper2>();
container.RegisterType<IMapper3, Mapper3>();
My container is legit for the majority of my app, and I can instate the IHandler object.
IHandler<IMapper1> Handler1 = container.Resolve<IHandler<IMapper1>>();
However, I cannot figure out how to pass the IMapper1 object into the generic parseCSV method so it will resolve in FileHelperEngine.
Does anyone know how to pass the Mapper object to FileHelperEngine using Unity? I would like to get that dependency off of the client code.
Upvotes: 1
Views: 777
Reputation: 27009
You have a dependency in your parseCSV
method. Therefore, you should inject that into your class as well. There are many ways to do that but I prefer, and I have seen many other devs also prefer, constructor injection.
Thus all you need is an interface and then inject an instance of a class which implements the interface into your constructor like this:
public interface IFileHelperEngine<T> where T : class
{
T[] ReadFile(string inputFileName);
}
public class Handler<T> : IHandler<T> where T : class
{
private IFileHelperEngine<T> fileHelperEngine;
public Handler(IFileHelperEngine<T> fileHelperEngine) //<----See this.
{
this.fileHelperEngine = fileHelperEngine;
}
public T[] parseCSV(string InputFileName)
{
if (File.Exists(InputFileName))
{
_inputFileName = InputFileName;
return this.fileHelperEngine.ReadFile(_inputFileName); //<--and this
}
throw new IOException($"{InputFileName} not found!");
}
}
This is actually good because now you can mock the IFileHelperEngine
when you are unit testing the Handler<T>
class.
FYI, you are not using .NET naming conventions; Locals should use camel case notation and method names should use Pascal Notation.
Upvotes: 1