这里是我的设置代码:
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.IGenericRepository
1[MyProject.TestObject] manager' of constructor 'Void .ctor(MyProject.IGenericRepository
1 [MyProject.TestObject])'。
用autofac注册此开放通用方法的正确方法是什么?
我不能使用类似builder.RegisterGeneric(GetType(GenericRepository(Of))).As(GetType(IGenericRepository(Of)))
之类的东西,因为具体的类在另一个未引用的项目中
答案 0 :(得分:1)
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<>));
}
答案 1 :(得分:0)
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)))