这是我的类,其中依赖项已解决
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
出现此异常时:
没有为此对象定义无参数构造函数。
有人请帮忙。我遇到了麻烦!
答案 0 :(得分:3)
我认为您对注册依赖项的方式感到困惑。
@Amy的评论更新:
您也未能注册MVC控制器
// You can register controllers all at once using assembly scanning...
builder.RegisterControllers(Assembly.GetExecutingAssembly());
当明确地注入依赖类时,也使用接口而不是具体类,就像你在容器中注册的一样。
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
}
答案 1 :(得分:1)
实际上,如果你深入研究并分析异常消息和堆栈跟踪,我相信你得到的异常并不会产生误导。您可以确切地找到容器无法找到和创建的服务 - 在这种情况下,UserService
中的AccountController
(以及Encryption
中的UserService
也是builder.RegisterType<UserService>()
)。 &#34;没有找到无参数构造函数的例外&#34;简单地说,在现有的带参数的构造函数中,有一个或多个参数无法通过容器解析,并且由于缺少无参数构造函数,因此无法创建所需的类型。
这也可能意味着您忘记在容器中注册您的控制器,因此Autofac不知道它应该将任何依赖注入控制器。
更进一步 - Autofac对注册非常明确 - 您只能注入/解决您在应用程序启动时注册的内容。
如果您只使用As<>
- 没有任何UserService
,则只能直接注入.As<>
。但是当您添加builder.RegisterType<UserService>().As<IUserService>()
:UserService
时,您不能再注入IUserService
,而是UserService
。为了保留注入AsSelf()
的可能性,您必须使用builder.RegisterType<UserService>().As<IUserService>().AsSelf()
:IUserService
。然后,您可以同时注入UserService
和As<>
。请记住,Autofac注册API很流畅,您可以根据需要修改IUserService
个。{/ p>
在Dependecy Injection世界中,我们不喜欢整合耦合的组件,因此不推荐注入具体类而不是接口 - 就像你所做的那样 - 你应该尽可能使用接口。因此,您的注册是正确的,但您应该在组件中注入UserService
而不是IEncryption
和Encryption
而不是builder.RegisterControllers(Assembly.GetExecutingAssembly());
。
它可以简化这些组件的潜在单元测试,使您可以轻松地模拟依赖项。
此外,您还应注册您的控制器:
subprocess.run('i=0; while [ $i -lt 3 ]; do i=`expr $i + 1`; echo $i; done', shell=True)