Autofac AsImplementedInterfaces无法解析依赖关系

时间:2016-10-25 19:31:03

标签: asp.net-mvc autofac ioc-container

这对我来说是一个很大的谜。当尝试解决依赖关系时,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();

无法判断是否有东西被加载,目前我正面临着天蓝色的问题。对于我来说,当我做一些调试会话时,在这里和那里更改代码片段并进行增量构建。然后出现此问题,但并非总是如此。为了解决这个问题,我简单地进行了完全重建,这就是它。

1 个答案:

答案 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()