【问题标题】:Dependency injection by type names按类型名称进行依赖注入
【发布时间】:2018-11-13 18:25:47
【问题描述】:

对于我的示例,我使用 Autofac(没有必要):

var r = builder.RegisterType<Helper>().As<IHelper>(); // usual using

我想做的是能够以某种方式注册类型:

string name1 = "Helper";

string name2 = "IHelper";

var r = builder.RegisterType<GetTypeFromName(name1)>().As<GetTypeFromName(name2)>();

可以用反射魔法吗?

【问题讨论】:

标签: c# .net reflection dependency-injection autofac


【解决方案1】:

您必须创建一种机制来“确定”您要注册哪些具体类型以及如何公开它们(AutoFac 中的As 部分)。以下是如何使用System.Type 注册的示例,因此缺少的部分是自己获取System.Types。

// get your Type(s)
Type concreteType = typeof(Helper);
Type asType = typeof(IHelper);

// Autofac registration call
builder.RegisterType(concreteType).As(asType);

正如您在上面的代码中看到的,您应该调用RegisterTypeAs 方法的非泛型版本。 (无论如何,通用版本实际上只是调用这些)。

【讨论】:

  • 嘿,我什至没有考虑非通用版本!是的,我能够同时获得这两种类型,但不幸的是,在解决之后,我得到了 'asType' 的 ComponentNotRegisteredException(IHelper)。有什么想法吗?
  • @amplifier - 类型 Helper 是否实现接口 IHelper
  • 是的,确实如此。检查它,否则我的“静态”解析器将无法工作
【解决方案2】:

通常要解析类型名称,您需要提供比类名称更多的信息。所以我猜答案是“不完全是”。

将字符串映射到类型的方法是Type.GetType,此处记录:https://docs.microsoft.com/en-us/dotnet/api/system.type.gettype?view=netframework-4.7.2

如您所见,在真空中,我们不能说"Helper""IHelper" 就足够了。您可能可以使用命名空间限定的类名。 (Helper 在“硬编码”语法中工作的原因当然是编译器可以利用using 语句来决定Helper 的含义。当@987654328 时该选项不起作用@ 试图在运行时理解一个字符串。)

如果您可以提供自定义解析器,也许您可​​以使其完全按照您的描述工作。

【讨论】:

  • 我可以通过这种方式获取 Helper 和 IHelper 的类型变量: Type typeArgument = Assembly.LoadFrom(assemblyPath).GetTypes().First(t => t.Name == className);
  • 当然,如果这适合您的用例,那很好。这意味着您知道该类来自哪个程序集,这是一个很好的起点。但也要注意 First 方法,如果程序集碰巧包含两个同名的类(在不同的命名空间中),它可能无法执行您想要的操作。
【解决方案3】:

如果您能够获取您要注册的类型的 Type 对象,则可以使用 RegisterType 方法的不同重载将其传递给 Autofac,如下所示:

var type = Assembly.LoadFrom(path).GetType(typeName);
builder.RegisterType(type);

【讨论】:

  • 太棒了!但是在通过 _container.Resolve(); 解析 IHelper 后,我得到 ComponentNotRegisteredException for 'asType' (IHelper)。
  • 如果具体类型和接口类型不同,你还是得像以前一样使用As()方法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-06-29
  • 2010-12-23
  • 2016-12-28
  • 2016-03-23
  • 2018-06-29
  • 1970-01-01
相关资源
最近更新 更多