我一直在MVC3中使用Autofac并且喜欢它.现在我试图用MVC4实现它.
我通过软件包管理器控制台安装了预发布版本的Autofac MVC4和Autofac WebApi(Install-Package Autofac.Mvc4 -Pre和Install-Package Autofac.WebApi -Pre)
我将IoC容器调整如下:
private static void SetAutofacContainer()
{
var builder = new ContainerBuilder();
builder.RegisterControllers(Assembly.GetExecutingAssembly());
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());
builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().InstancePerHttpRequest().InstancePerApiRequest();
builder.RegisterType<DatabaseFactory>().As<IDatabaseFactory>().InstancePerHttpRequest().InstancePerApiRequest();
builder.RegisterType<RepositoryWrapper>().As<RepositoryWrapper>().InstancePerHttpRequest().InstancePerApiRequest();
builder.RegisterType<ServiceWrapper>().As<ServiceWrapper>().InstancePerHttpRequest().InstancePerApiRequest();
// Repositories
builder.RegisterAssemblyTypes(typeof(UserRepository).Assembly).Where(t => t.Name.EndsWith("Repository")).AsImplementedInterfaces().InstancePerHttpRequest().InstancePerApiRequest();
// Services
builder.RegisterAssemblyTypes(typeof(UserService).Assembly).Where(t => t.Name.EndsWith("Service")).AsImplementedInterfaces().InstancePerHttpRequest().InstancePerApiRequest();
IContainer container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
GlobalConfiguration.Configuration.DependencyResolver = new AutofacWebApiDependencyResolver(container);
}
Run Code Online (Sandbox Code Playgroud)
当我运行应用程序(通过访问API控制器)时,我得到异常:" Controllers.UserController'没有默认构造函数 "
控制器看起来像这样:
namespace Controllers
{
[Authorize]
public class UserController : ApiController
{
private ServiceWrapper _services;
public UserController(ServiceWrapper services)
{
_services = services;
}
// GET api/user/{userrequest}
public IQueryable<User> Get(UserRequest request)
{
if …
Run Code Online (Sandbox Code Playgroud) 的洋葱结构是结构化的应用程序的方式来保持(例如在项目:关注和松耦合的分离http://onionarch.codeplex.com/).依赖注入/解析是此体系结构的一个关键方面,因为它用于将所有层绑定在一起.
上面的链接包含一个关于如何使用Onion分层构建ASP.NET MVC的示例应用程序.我非常喜欢它,但是大多数这些例子都使用了Ninject(我们都知道它很慢).我想知道是否有人可以详细说明如何将不同的DI工具(如SimpleInjector,Unity或Autofac)集成到洋葱项目中.
关键是所有层只有1个依赖关系(包括MVC项目),即Core层.除依赖性分辨率图层外,该图层可以引用所有图层.
我很难将MVC项目设置为启动项目,使用DI,而不是在MVC层中包含对DI工具的引用.
我正在构建一个查询管道(使用IQueryHandler的装饰器模式),其中,在实际执行查询之前,处理了许多横切关注点.其中一个问题是验证,我正在使用Fluent验证库.
Simple Injector是IoC容器的首选,我使用它来使用通用的逆变和以下注册来注册每个IQueryValidationHandler:
container.RegisterManyForOpenGeneric(typeof(IQueryValidationHandler<>), container.RegisterAll, _assemblies);
Run Code Online (Sandbox Code Playgroud)
这非常适合解决以下实现:
public class QueryValidationHandler : IQueryValidationHandler<IQuery>{ }
Run Code Online (Sandbox Code Playgroud)
该类中可用的查询是一种具体的IQuery类型.但是,当我尝试将基于IQuery的IValidator(通过构造函数注入)注入QueryValidationHandler时,使用以下代码和注册:
码:
public class QueryValidationHandler : IQueryValidationHandler<IQuery>
{
private IValidator< IQuery > _validator;
public QueryValidationHandler(IValidator<IQuery> validator)
{
_validator = validator;
}
Run Code Online (Sandbox Code Playgroud)
注册:
container.RegisterManyForOpenGeneric(typeof (IValidator<>), container.RegisterAll, _assemblies);
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
QueryValidationHandler类型的构造函数包含IValidator <IQuery>类型的参数,其名称为"validator",未注册.请确保在容器中注册了IValidator <IQuery>,或者更改了QueryValidationHandler的构造函数.
有没有办法为注入QueryValidationHandler的具体类型的IQuery获取IValidator的实现?
更新
在史蒂文的出色回答之后,我仍然陷入困境(同样的例外).很可能是因为我试图将Fluent Validators AbstractValidator <T>的实现注册为IValidator <T>.在之前的项目中,我能够进行以下注册:
container.RegisterManyForOpenGeneric(typeof(IValidator<>), typeof(FindProductsForCompanyQuery).Assembly);
Run Code Online (Sandbox Code Playgroud)
对于以下实现:
public class FindProductsForCompanyQueryValidator : AbstractValidator<FindProductsForCompanyQuery>
{
public FindProductsForCompanyQueryValidator()
{
RuleFor(q => q.CompanyId).NotNull();
}
}
Run Code Online (Sandbox Code Playgroud)
上面提到的QueryValidationHandler应该注入程序集中的所有AbstractValidator实现,因此它可以检查错误并在验证失败时抛出异常.