首先,我尝试在我的 dotnet 项目中使用 n 层架构。 这是我的错误消息:尝试激活“WebAPI.Controllers.AuthController”时无法解析类型“Business.Abstract.IAuthService”的服务
所以基本上我的 Core 项目中有一个名为 CoreModule 的文件,我已经为其创建了一些扩展,并且它正在注册我的核心依赖项。 之后我在业务层中使用 Autofac。这是我为 AuthManager 注册 IAuthService 的地方。 然后在我的 Program.cs 中,我使用 Autofac 的 Populate 方法来合并我自己的依赖项和由 Autofac 创建的其他依赖项。 我真的不知道我在哪里犯了错误。如果您能帮助我,我很高兴。
这是我的Program.cs
using Autofac.Extensions.DependencyInjection;
using Autofac;
using Core.DependencyResolvers;
using Core.Extensions;
using Core.Utilities.IoC;
using Core.Utilities.Security.Encryption;
using Core.Utilities.Security.JWT;
using DataAccess.Concrete.EntityFramework;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
using Business.DependencyResolvers.Autofac;
using Business.Abstract;
using Business.Concrete;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
builder.Services.AddCors();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var tokenOptions = builder.Configuration.GetSection("TokenOptions").Get<TokenOptions>();
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidIssuer = tokenOptions.Issuer,
ValidAudience = tokenOptions.Audience,
ValidateIssuerSigningKey = true,
IssuerSigningKey = SecurityKeyHelper.CreateSecurityKey(tokenOptions.SecurityKey)
};
});
var serviceCollection = new ServiceCollection();
serviceCollection.AddDependencyResolvers(new ICoreModule[]
{
new CoreModule()
});
serviceCollection.AddDbContext<NorthwindContext>();
//TODO: refactor
var containerBuilder = new ContainerBuilder();
containerBuilder.Populate(serviceCollection);
containerBuilder.RegisterModule(new AutofacBusinessModule());
var container = containerBuilder.Build();
var serviceProvider = new AutofacServiceProvider(container);
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.ConfigureCustomExceptionMiddleware();
app.UseCors(builder=>builder.WithOrigins("http://localhost:4200").AllowAnyHeader());
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
这是我的AuthController
using Business.Abstract;
using Entities.DTOs;
using Microsoft.AspNetCore.Mvc;
using Business.ValidationRules.FluentValidation;
using Core.Aspects.Autofac.Validation;
using Core.Entities.Concrete;
using Core.Utilities.Results;
using IResult = Core.Utilities.Results.IResult;
namespace WebAPI.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class AuthController : Controller
{
private IAuthService _authService;
public AuthController(IAuthService authService)
{
_authService = authService;
}
[HttpPost("login")]
[ValidationAspect(typeof(UserValidator))]
public IResult Login(UserForLoginDto userForLoginDto)
{
var userToLogin = _authService.Login(userForLoginDto);
if (!userToLogin.Success)
{
return new ErrorResult(userToLogin.Message);
}
var result = _authService.CreateAccessToken(userToLogin.Data);
if (result.Success)
{
userToLogin.Data.Token = result.Data;
return new SuccessDataResult<User>(userToLogin.Data);
}
return new ErrorResult(result.Message);
}
[HttpPost("register")]
public IResult Register(UserForRegisterDto userForRegisterDto)
{
var userExists = _authService.UserExists(userForRegisterDto.Email);
if (!userExists.Success)
{
return new ErrorResult(userExists.Message);
}
var registerResult = _authService.Register(userForRegisterDto, userForRegisterDto.Password);
var result = _authService.CreateAccessToken(registerResult.Data);
if (result.Success)
{
registerResult.Data.Token = result.Data;
return new SuccessDataResult<User>(registerResult.Data);
}
return new ErrorResult(result.Message);
}
}
}
这是我的 AutofacBusinessModule
using Autofac;
using Autofac.Extras.DynamicProxy;
using Business.Abstract;
using Business.Concrete;
using Castle.DynamicProxy;
using Core.Utilities.Interceptors;
using Core.Utilities.Security.JWT;
using DataAccess.Abstract;
using DataAccess.Concrete.EntityFramework;
namespace Business.DependencyResolvers.Autofac
{
public class AutofacBusinessModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<ProductManager>().As<IProductService>().SingleInstance();
builder.RegisterType<EfProductDal>().As<IProductDal>().SingleInstance();
builder.RegisterType<CategoryManager>().As<ICategoryService>().SingleInstance();
builder.RegisterType<EfCategoryDal>().As<ICategoryDal>().SingleInstance();
builder.RegisterType<UserManager>().As<IUserService>();
builder.RegisterType<EfUserDal>().As<IUserDal>();
builder.RegisterType<AuthManager>().As<IAuthService>().SingleInstance();
builder.RegisterType<JwtHelper>().As<ITokenHelper>().SingleInstance();
var assembly = System.Reflection.Assembly.GetExecutingAssembly();
builder.RegisterAssemblyTypes(assembly).AsImplementedInterfaces()
.EnableInterfaceInterceptors(new ProxyGenerationOptions()
{
Selector = new AspectInterceptorSelector()
}).SingleInstance();
}
}
}
这是我的核心模块
using Core.CrossCuttingConcerns.Caching;
using Core.CrossCuttingConcerns.Caching.Microsoft;
using Core.Utilities.IoC;
using Core.Utilities.Security.JWT;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
namespace Core.DependencyResolvers
{
public class CoreModule : ICoreModule
{
public void Load(IServiceCollection serviceCollection)
{
serviceCollection.AddMemoryCache();
serviceCollection.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
serviceCollection.AddSingleton<ICacheManager, MemoryCacheManager>();
}
}
}
这是我的 ServiceCollectionExtension
using Core.Utilities.IoC;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Text;
namespace Core.Extensions
{
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddDependencyResolvers
(this IServiceCollection serviceCollection, ICoreModule[] modules)
{
foreach (var module in modules)
{
module.Load(serviceCollection);
}
return ServiceTool.Create(serviceCollection);
}
}
}
这是错误的所有堆栈跟踪
crit: Core.Extensions.ExceptionMiddleware[0]
Unable to resolve service for type 'Business.Abstract.IAuthService' while attempting to activate 'WebAPI.Controllers.AuthController'.
crit: Core.Extensions.ExceptionMiddleware[0]
at Microsoft.Extensions.DependencyInjection.ActivatorUtilities.ThrowHelperUnableToResolveService(Type type, Type requiredBy)
at lambda_method14(Closure, IServiceProvider, Object[])
at Microsoft.AspNetCore.Mvc.Controllers.ControllerFactoryProvider.<>c__DisplayClass6_0.<CreateControllerFactory>g__CreateController|0(ControllerContext controllerContext)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
at Core.Extensions.ExceptionMiddleware.InvokeAsync(HttpContext httpContext, ILogger`1 logger) in D:\WorkFiles\ProjectWiseSoftAspNet\Core\Extensions\ExceptionMiddleware.cs:line 26
我也尝试添加 AddScoped 但它不起作用,我查看了 Autofac 文档以了解我在做什么,但它也说了与我在程序中所做的相同的事情。cs
据我所知,要使用第 3 方 DI 容器,您需要替换默认容器。沿着这些思路的东西(未经测试,需要
Autofac.Extensions.DependencyInjection
nuget):
builder.Host
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureContainer<ContainerBuilder>(builder =>
{
builder.RegisterModule(new AutofacBusinessModule());
});
而不是你处理
ContainerBuilder
。
参见: