C#通过泛型和依赖注入来引入类名吗?

时间:2016-08-21 15:03:53

标签: c# generics dependency-injection ioc-container

我正在使用外部FileHelpers库通过创建一个属性与csv列匹配的类来验证我的csv文件 http://www.filehelpers.net/example/ErrorHandling/ErrorMode.SaveAndContinue/

通过这个实现,我需要传递一个类来启动验证引擎,如下所示

var engine = new DelimitedFileEngine<Customer>();

但是我有不同类型的文件,因此需要对类名Customer进行参数化。

根据某些值,该类可以是Customer,Employee等。

我正在尝试使用

public List<T> ValidateFileData<T>(T className)
{

var engine = new DelimitedFileEngine<T>();
}

我不确定如何使用它。 以及如何根据某些字符串值设置Customer或Employee类并将其作为参数传递给此方法? 我可以选择使用unitycontainer并进行依赖注入。关于我的设计应该如何帮助的任何线索和见解..

1 个答案:

答案 0 :(得分:1)

我假设您希望逻辑像这个伪代码一样工作:

IDelimitedFileEngine engine= null; // because you're programming to interfaces, right?
switch(className)
{
   case "Customer":
      engine = new DelimitedFileEngine<Customer>();
      break;
   case "Employee":
      engine = new DelimitedFileEngine<Employee>();
      break;
}

除了我上面使用的逐案逻辑之外,确实没有办法将字符串参数映射到泛型类T的类型Something<T>。如果您想将结果分配给一个无论T是什么都可以工作的变量,那就不是了。 (除非Something<T>基于我的示例中的非通用ISomething。)

那么,你能做什么?好吧,你可以试验System.Linq.Expressions,它可以动态构建可以编译和执行的表达式。我的结果好坏参半,但它可能适合你。

你可以放弃使用泛型并使用老式反射的想法。它会比你想要的慢,但速度可能不是你最关心的问题。

var targetType = Type.GetType(className);
var engine = new DelimitedFileEngine(targetType); 

这样做的好处是可以适应你想要抛出的任何新类型,而不是受限于你编码的类型(如我的例子中所示)。

你甚至可以在反射的帮助下,做一些与XmlSerializer相同的事情,并动态生成你自己的帮助程序集。

或者你可以咬紧牙关并使用我上面的逻辑,虽然它是丑陋和不可扩展的。