我目前有一个通过反射得到的运行时类型。我需要创建这种类型的实例,以便像这样使用Activator类:
(T)Activator.CreateInstance(instance)
我将Autofac用作IoC,并在整个应用程序中使用DI。不幸的是,我无法在这些实例上使用DI,因为当我尝试通过构造函数注入依赖项时,该Activator类无法解析依赖项。
是否有一个Autofac方法可以执行相同的操作,但是使用我的Autofac注册来解决依赖关系?
谢谢
答案 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()
添加注册。它已被标记为已过期一年左右,并且即将发布。 。它不会为您提供长期解决方案。