使用autofac无法解析打开泛型类型

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用autofac无法解析打开泛型类型相关的知识,希望对你有一定的参考价值。

继承我的设置代码:

Dim builder As New ContainerBuilder
Dim assemblies = BuildManager.GetReferencedAssemblies().Cast(Of Assembly).ToArray

builder.RegisterModule(Of AutofacWebTypesModule)
builder.RegisterAssemblyTypes(assemblies).AsClosedTypesOf(GetType(IGenericRepository(Of)))

'Controllers
builder.RegisterControllers(assemblies)

'Model Binders
builder.RegisterModelBinders(assemblies)
builder.RegisterModelBinderProvider()

Dim container = builder.Build

和控制器代码:

Public Class TestController
    Inherits System.Web.Mvc.Controller

    Public Sub New(manager As IGenericRepository(Of TestObject))

    End Sub

    Public Function Test() As ContentResult

        Return Content("OK")

    End Function

End Class

现在,当我导航到/Test/Test时,我收到以下错误:

使用可用的服务和参数可以调用在'MyProject.TestController'类型上找到'Autofac.Core.Activators.Reflection.DefaultConstructorFinder'的构造函数:无法解析参数'MyProject.IGenericRepository1[MyProject.TestObject] manager' of constructor 'Void .ctor(MyProject.IGenericRepository1 [MyProject.TestObject])'。

使用autofac注册这个开放式通用的正确方法是什么?

我不能使用像builder.RegisterGeneric(GetType(GenericRepository(Of))).As(GetType(IGenericRepository(Of)))这样的东西,因为具体的类是在一个不同的,未引用的项目中

答案

AsClosedTypesOf方法将注册实现特定开放类型的封闭类型(非通用)。

如果一个程序集包含IGenericRepository<TestObject>的封闭实现,则代码将起作用

public class TestRespository : IGenericRepository<TestObject> 
{ }

在您的情况下,您想要注册一个开放的通用,没有组装扫描它是通过使用完成

builder.RegisterGeneric(typeof(GenericRepository<>)).As(typeof(IGenericRepository<>))

但由于此Github问题(Support registering open generic types when scanning assemblies)中解释的限制,这是不可能的。

一个常见的解决方法是进行自己的装配扫描:

var repositories = assembly.GetTypes().Where(t =>
{
    return t.GetTypeInfo()
        .ImplementedInterfaces.Any(
            i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IGenericRepository<>));
});

foreach (var repository in repositories)
{
    builder.RegisterGeneric(repository).As(typeof(IGenericRepository<>));
}
另一答案

Cyril帮助我意识到assemblies数组包含我想要使用的类型。所以我能够解决这个问题:

Dim genericType = assemblies.Single(Function(x) x.FullName.Contains("OtherAssembly")).
     DefinedTypes.        
     Single(Function(x) x.FullName.Contains("GenericRepository"))
builder.RegisterGeneric(genericRepo.UnderlyingSystemType).As(GetType(IGenericRepository(Of)))

以上是关于使用autofac无法解析打开泛型类型的主要内容,如果未能解决你的问题,请参考以下文章

IoC容器Autofac正篇之类型注册

autoFac——茴字的三种写法

Autofac的基本使用---目录

Autofac 和逆变:解析为更多派生类型

autofac使用架构体现泛型注入

Autofac 的点滴