【发布时间】:2019-05-20 23:30:18
【问题描述】:
我正在构建一个 Web 应用程序,其中有很多控制器及其相应的操作方法。
我想将每个异常都保存在数据库中,因此我创建了 ExceptionService(其中注入了DbContext)。
假设这是我的控制器的一般形式:
[Route("api/[controller]")]
[ApiController]
public class UserController : ControllerBase
{
private readonly UserManager userManager;
private readonly IExceptionService exceptionService;
public UserController(UserManager userManager, IExceptionService exceptionService)
{
this.userManager = userManager;
this.exceptionService = exceptionService;
}
[HttpPost]
public async Task<IActionResult> Post([FromBody] User user)
{
try
{
//some code
}
catch (Exception e)
{
exceptionService.Save(e);
//some code
}
}
}
为了避免出现这么多的 try-catch 块,我决定创建一个如下所示的过滤器:
public class ApiExceptionFilterAttribute : ExceptionFilterAttribute
{
private readonly IExceptionService exceptionService;
public ApiExceptionFilterAttribute(IExceptionService exceptionService)
{
this.exceptionService = exceptionService;
}
public override void OnException(ExceptionContext context)
{
Exception e = context.Exception;
exceptionService.Save(e);
//some code
}
}
StartUp.cs 中的 ConfigureServices 方法中的代码如下所示(为简单起见,删除了一些代码):
services
.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
.AddJsonOptions(options => options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);
services
.AddDbContext<AppDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("Default")));
services.AddScoped<UserManager>();
services.AddScoped<SignInManager>();
services.AddScoped<IExceptionService, ExceptionService>();
services.AddSingleton<IConfigureOptions<MvcOptions>, ConfigureMvcOptions>();
ConfgureMvcOptions 类如下所示:
public class ConfigureMvcOptions : IConfigureOptions<MvcOptions>
{
private readonly IExceptionService exceptionService;
public ConfigureMvcOptions(IExceptionService exceptionService)
{
this.exceptionService = exceptionService;
}
public void Configure(MvcOptions options)
{
options.Filters.Add(new ApiExceptionFilterAttribute(exceptionService));
}
}
当我运行此应用程序时,我收到以下错误:
System.InvalidOperationException: 'Cannot consume scoped service 'SmartWay.Services.IExceptionService' from singleton 'Microsoft.Extensions.Options.IConfigureOptions`1[Microsoft.AspNetCore.Mvc.MvcOptions]'.'
如果我将 IExceptionServcise 的生命周期更改为瞬态,那么我必须这样做 Dbcontext,然后是 DbContextOptions... 好像不对..
那么,我该如何解决这个问题呢?
【问题讨论】:
-
你实际上是在重塑 Elmah,只是为了让你知道
-
连接数据库失败出现异常怎么办?
-
@mjwills 我想我会抓住它并且什么都不做,或者我会将它保存在文本文件中
-
@AlexanderMujirishvili 您正在混合横切关注点IMO。重新考虑当前的设计选择。
-
可能把所有异常都保存在文件中会更好,你觉得呢?
标签: c# asp.net-core