使用Autofac创建运行时类型的实例

时间:2018-06-21 17:15:48

标签: c# .net autofac

我目前有一个通过反射得到的运行时类型。我需要创建这种类型的实例,以便像这样使用Activator类:

(T)Activator.CreateInstance(instance)

我将Autofac用作IoC,并在整个应用程序中使用DI。不幸的是,我无法在这些实例上使用DI,因为当我尝试通过构造函数注入依赖项时,该Activator类无法解析依赖项。

是否有一个Autofac方法可以执行相同的操作,但是使用我的Autofac注册来解决依赖关系?

谢谢

1 个答案:

答案 0 :(得分:2)

我认为您有两个选择,因为通常来说,Autofac需要在容器内部具有类型才能对其进行解析。

最简单,最直接的解决方案是只注册类型。如果在构建容器时引用了Type,则可以使用它来向Autofac注册并解决。

Type customType = GetTheRuntimeType();
var builder = new ContainerBuilder();
builder.RegisterType(customType);

如果需要,您可以添加更多内容(InstancePerLifetimeScope()As<IInterface>()或其他任何方式),但这是可行的。

如果没有在构建容器时具有该类型,则可以选择在事实之后手动注入属性。服务位置,但这意味着您可以分开创建类型。

Type customType = GetTheRuntimeType();
var builder = new ContainerBuilder();
// register everything else, then
var container = builder.Build();
using(var scope = container.BeginLifetimeScope())
{
  var instance = Activator.CreateInstance(customType);
  scope.InjectUnsetProperties(instance);
}

这不是构造函数注入,而是属性。但这很容易。

第三个选项是集成度最高但可能最难的选项。您可以implement a registration source告诉Autofac您的类型。我不会将代码放在这里,因为其中有很多内容,而且我不是编译器,而是read the docs and check it out。在文档中有示例。当您从未显式注册IEnumerable<T>时,这就是Autofac动态处理这种情况的方式。您可以提出所需的任何一组运行时类型,并且可以使用注册源将所有这些类型动态地插入到容器中。

如果您有能力做第一个选择并只注册类型,我建议您这样做。这是进行良好集成的最简单方法。

属性注入可以正常工作,但有点像黑客。取决于您的解决方案需要使用多长时间,或者只需要使它真正快速地工作。

注册源解决方案绝对是最可靠的。如果在创建容器之前没有运行时类型,那么这是最佳选择。从一开始就很难工作,但是它会更具扩展性,因为您可以从中附带任何其他运行时类型需求。

无论您做什么,在构建容器后,都不要使用Update()添加注册。它已被标记为已过期一年左右,并且即将发布。 。它不会为您提供长期解决方案。