这对我来说是一个很大的谜。当尝试解决依赖关系时,autofac会不时(无法找到模式)失败,这里有错误信息:
没有任何构造函数与' Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type' IsThereAnyNews.Mvc.Controllers.HomeController'可以使用可用的服务和参数调用: 无法解析参数' IsThereAnyNews.DataAccess.IRssChannelsRepository rssRepository'构造函数' Void .ctor(IsThereAnyNews.Services.IUserAuthentication,IsThereAnyNews.Services.ILoginService,IsThereAnyNews.Services.ISessionProvider,IsThereAnyNews.DataAccess.IRssChannelsRepository)'。
这是我如何连接autofac
public static void RegisterDependencies()
{
var builder = new ContainerBuilder();
builder.RegisterControllers(Assembly.GetCallingAssembly());
builder.RegisterAssemblyTypes(AppDomain.CurrentDomain.GetAssemblies())
.Where(t => t.Name.EndsWith("Repository"))
.AsImplementedInterfaces();
builder.RegisterAssemblyTypes(AppDomain.CurrentDomain.GetAssemblies())
.Where(t => t.Name.EndsWith("Service"))
.AsImplementedInterfaces();
// other registrations goes here
var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
}
项目设置如下:
ASP.MVC
-> Interfaces (where needed)
-> Autofac
-> Interface
-> Implementations (*Repository, *Services)
然而,对于一些神秘的(对我来说)理由,我的脸被这个错误打了一巴掌。任何人都可以向我解释,我做错了什么
修改 这里是RssChannelsRepository
的实现public class RssChannelsRepository : IRssChannelsRepository
{
private readonly ItanDatabaseContext database;
public RssChannelsRepository(ItanDatabaseContext database)
{
this.database = database;
}
}
ItanDatabaseContext的注册位置如下:
builder.RegisterType<ItanDatabaseContext>().InstancePerLifetimeScope();
无法判断是否有东西被加载,目前我正面临着天蓝色的问题。对于我来说,当我做一些调试会话时,在这里和那里更改代码片段并进行增量构建。然后出现此问题,但并非总是如此。为了解决这个问题,我简单地进行了完全重建,这就是它。
答案 0 :(得分:3)
问题可能是AppDomain.CurrentDomain.GetAssemblies()
电话引起的。根据{{3}}方法:
获取已加载到此应用程序域的执行上下文中的程序集。
如果尚未加载程序集,则不会从列表中返回该程序集。由于您的引导代码在应用程序启动期间很早就运行了,因此可能没有JIT的方法静态地依赖于包含存储库的程序集中的类型。如果是这种情况,那个程序集将不会被加载,也不会从GetAssemblies()
方法返回,导致Autofac中没有注册。
要确保以确定的方式加载所有程序集,您应该调用MSDN。例如:
public static void RegisterDependencies()
{
BuildManager.GetReferencedAssemblies();
var builder = new ContainerBuilder();
builder.RegisterAssemblyTypes(AppDomain.CurrentDomain.GetAssemblies())
.Where(t => t.Name.EndsWith("Repository"))
.AsImplementedInterfaces();
// ...
}
使用从GetReferencedAssemblies
返回的程序集作为Autofac的输入效率更高,因为AppDomain.GetAssemblies()
也将返回所有System.*
程序集,这将导致Autofac通过它们好。例如:
public static void RegisterDependencies()
{
var assemblies = BuildManager.GetReferencedAssemblies().Cast<Assembly>().ToArray();
var builder = new ContainerBuilder();
builder.RegisterAssemblyTypes(assemblies)
.Where(t => t.Name.EndsWith("Repository"))
.AsImplementedInterfaces();
// ...
}
Autofac文档中的所有内容均为BuildManager.GetReferencedAssemblies()。