【问题标题】:Exception in Autofac : No parameterless constructor defined for this objectAutofac 中的异常:没有为此对象定义无参数构造函数
【发布时间】:2017-08-23 15:47:06
【问题描述】:

这是我解决依赖关系的类

namespace TestProj
{
    public static class Bootstrapper
    {
        public static void Run()
        {
            SetAutofacWebAPI();
        }

        private static void SetAutofacWebAPI()
        {
            var builder = new ContainerBuilder();

            builder.RegisterType<UserService>().As<IUserService>().InstancePerRequest();
            builder.RegisterType<Encryption>().As<IEncryption>().InstancePerRequest();

            DependencyResolver.SetResolver(new AutofacDependencyResolver(builder.Build()));
        }
    }
}

在 Global.asax 中,我有这个:Bootstrapper.Run();


这是我的 UserService 类:

public class UserService : IUserService
{
    private readonly IEncryption _Encryption;

    public UserService(Encryption Encryption)
    {
        _Encryption = Encryption;
    }
    //Rest of the service here
}

Encryption 类是类似的。


控制器就在这里:

public class UserController : Controller
{
    private readonly IUserService _UserService;
    public AccountController(UserService UserService)
    {
        _UserService = UserService;
    }

    public JsonResult GetLoginLogs(int Id)
    {
        var Logs = _UserService.GetLoginLogById(Id);
        return Json(Logs, JsonRequestBehavior.AllowGet);
    }
    //The rest of the controller
}

这是版本信息:

Autofac : 3.5.2
MVC : 4.0.40804.0
DOTNET : 4

然后,当尝试localhost:5000/Account/GetLoginLogs/1 时出现此异常:

没有为此对象定义无参数构造函数。

请有人帮忙。我遇到了严重的麻烦!

【问题讨论】:

  • 我认为您对如何显式注入类感到困惑。注入依赖类时使用接口而不是具体类
  • 您将UserService 注册为IUserService。您也未能注册您的 MVC 控制器。
  • 检查link,与上面的艾米在同一行
  • 感谢@Amy 你的评论很有帮助!

标签: c# .net asp.net-mvc-4 dependency-injection autofac


【解决方案1】:

我认为您对注册依赖项的方式感到困惑。

@Amy 从 cmets 更新:

您也未能注册您的 MVC 控制器

// You can register controllers all at once using assembly scanning...
builder.RegisterControllers(Assembly.GetExecutingAssembly());

来源:documentation

当显式注入依赖类时,也要使用接口而不是具体类,因为这是您在容器中注册的。

public class UserService : IUserService {
    private readonly IEncryption _Encryption;

    public UserService(IEncryption Encryption) {
        _Encryption = Encryption;
    }
    //Rest of the service here
}

public class UserController : Controller {
    private readonly IUserService _UserService;

    public AccountController(IUserService UserService) {
        _UserService = UserService;
    }

    public JsonResult GetLoginLogs(int Id) {
        var Logs = _UserService.GetLoginLogById(Id);
        return Json(Logs, JsonRequestBehavior.AllowGet);
    }
    //The rest of the controller
}

【讨论】:

  • @PrashanthBenny 这是框架在无法初始化控制器时抛出的标准误导性错误。我同意这是一条奇怪的错误消息。
  • 恩科西帮助很大。无论如何,这是深夜在我的地方。明天让我试试你的解决方案!
  • 看起来您使用的是 MVC,而不是 Web API(控制器继承自 Controller,而不是 ApiController),因此您应该使用 builder.RegisterControllers(Assembly.GetExecutingAssembly());,而不是 builder.RegisterApiControllers(Assembly.GetExecutingAssembly()); 注册控制器。跨度>
  • @tdragon 你是对的。我从文档中复制了它并忽略了那个细节。谢谢。会更新。
  • 非常感谢...大家!这次你救了我的命:)
【解决方案2】:

实际上,如果您深入了解异常消息并分析异常消息和堆栈跟踪,我相信您得到的异常不会误导。您会确切地找到容器无法找到和创建的服务 - 在这种情况下,它将是 AccountController 中的 UserService(后来,UserService 中的 Encryption 也是如此)。 “找不到无参构造函数”的异常只是说在现有的带参数构造函数中存在一个或多个参数无法被容器解析,并且由于缺少无参数构造函数,因此无法创建所需的类型。

这也可能意味着您忘记在容器中注册控制器,因此 Autofac 不知道应该将任何依赖项注入控制器。

更进一步 - Autofac 的注册非常明确 - 您只能注入/解析您在应用程序启动时注册的内容。 如果您只是使用builder.RegisterType&lt;UserService&gt;() - 没有任何As&lt;&gt;,您只能直接注入UserService。但是当你添加.As&lt;&gt;:builder.RegisterType&lt;UserService&gt;().As&lt;IUserService&gt;()时,你不能再注入UserService,而是IUserService。为了保持注入UserService 的可能性,您必须使用AsSelf()builder.RegisterType&lt;UserService&gt;().As&lt;IUserService&gt;().AsSelf()。然后,您可以同时注入IUserServiceUserService。请记住,Autofac 注册 API 是流畅的,您可以修改任意数量的 As&lt;&gt;

在 Dependecy Injection 世界中,我们不喜欢整齐耦合的组件,因此不建议像您那样注入具体类而不是接口 - 您应该尽可能使用接口。所以您的注册是正确的,但您应该在组件中注入 IUserService 而不是 UserServiceIEncryption 而不是 Encryption。 它将简化这些组件的潜在单元测试,让您可以轻松地模拟依赖项。

此外,您还应该注册您的控制器:

builder.RegisterControllers(Assembly.GetExecutingAssembly())‌​;

【讨论】:

  • 我只是从 nopcommerce 项目中复制了使用构造函数注入的样式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-29
  • 2016-04-25
  • 2018-02-11
  • 1970-01-01
相关资源
最近更新 更多