1

Ok, ça me rend fou! J'ai une méthode générique dans une classe générique.Passer un type de référence à la méthode générique avec Unity

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!"); 
     } 
    } 
} 

J'ai enregistré le générique dans un conteneur IoC en tant que tel:

container.RegisterType(typeof(IHandler<>), typeof(Handler<>)); 

Avec plusieurs cartographes pour analyser les fichiers avec le package FileHelpers

container.RegisterType<IMapper1, Mapper1>(); 
container.RegisterType<IMapper2, Mapper2>(); 
container.RegisterType<IMapper3, Mapper3>(); 

Mon conteneur est légitime pour la la majorité de mon application, et je peux installer l'objet IHandler.

IHandler<IMapper1> Handler1 = container.Resolve<IHandler<IMapper1>>(); 

Cependant, je ne peux pas comprendre comment passer l'objet IMapper1 dans la méthode parseCSV générique de sorte qu'il résoudra dans FileHelperEngine.

Est-ce que quelqu'un sait comment passer l'objet Mapper à FileHelperEngine en utilisant Unity? Je voudrais retirer cette dépendance du code client.

+1

Et vous ne pouvez pas simplement passer un 'IMapper1' dans le constructeur de' Handler '? – DavidG

Répondre

1

Vous avez une dépendance dans votre méthode parseCSV. Par conséquent, vous devriez également l'injecter dans votre classe. Il y a plusieurs façons de le faire mais je préfère, et j'ai vu beaucoup d'autres développeurs aussi, préférer l'injection de constructeurs.

Ainsi tout ce que vous avez besoin est une interface, puis injecter une instance d'une classe qui implémente l'interface dans votre constructeur comme ceci:

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!"); 
    } 
} 

Ceci est en fait bien parce que vous pouvez maintenant se moquer de la IFileHelperEngine lorsque vous êtes unité testant la classe Handler<T>.

FYI, vous n'utilisez pas les conventions de dénomination .NET; Les sections locales doivent utiliser la notation chameau notation et les noms de méthodes doivent utiliser Pascal Notation.

+0

Excellent! Merci pour votre réponse rapide! On dirait que je vais dormir ce soir. – Jason