我试图将ApplicationDbcontext注入iLogger。
当我在_context variable
或CustomLoggerProvider
中使用CustomLoggerExtension
时,这是工作。
当软件CreateLogger
创建CustomLogger
的实例时,ApplicationDbContext
遇到了问题,当我使用_context
变量访问数据库时,应用程序崩溃了和无效。
以下是错误日志:
System.ObjectDisposedException HResult = 0x80131622 Messaggio =无法 访问已处置的对象。导致此错误的常见原因是处理 依赖注入解决的上下文,然后再进行 尝试在应用程序的其他位置使用相同的上下文实例。 如果在上下文上调用Dispose(),则可能会发生这种情况,或者 将上下文包装在using语句中。如果您使用依赖项 注入,您应该让依赖注入容器保重 处理上下文实例的方法。
Origine = Microsoft.EntityFrameworkCore Analisi dello堆栈:在 Microsoft.EntityFrameworkCore.DbContext.CheckDisposed()在 Microsoft.EntityFrameworkCore.DbContext.Add [TEntity](TEntity实体)
在Microsoft.EntityFrameworkCore.Internal.InternalDbSet1.Add(TEntity entity) at Application.Services.EventLogDB.saveInDb(Cliente c) 28 at Application.Models.DbLogger.CustomLogger.Log[TState](LogLevel logLevel, EventId eventId, TState state, Exception exception, Func
3 格式))在C:\ Users ...... \ Models \ DbLogger \ CustomLogger.cs:第122行 在 Microsoft.Extensions.Logging.Logger.g__LoggerLog | 12_0 [TState](LogLevel logLevel,EventId,eventId,ILogger记录器,异常,Func3 formatter, List
1&异常,TState和状态)
我认为这是服务生命周期的问题。
有人知道解决方案吗?
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
services.AddControllersWithViews();
services.AddRazorPages();
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory, IServiceProvider serviceProvider)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
endpoints.MapRazorPages();
});
var serviceHttp = serviceProvider.GetService<IHttpContextAccessor>();
var serviceDbContext = serviceProvider.GetService<GestionaleOfficinaContext>();
// THIS IS METHOD THAT SHOWS THE BAD BEHAVIOUR
// Inside logger I need of Http context service and applicationDbContext
loggerFactory.AddCustomLogger(serviceHttp, serviceDbContext);
}
}
public static class CustomLoggerExtensions
{
public static ILoggerFactory AddCustomLogger(this ILoggerFactory factory, IHttpContextAccessor accessor, ApplicationDbContext_context,
Func<string, LogLevel, bool> filter = null)
{
factory.AddProvider(new CustomLogProvider(filter, accessor, _context));
return factory;
}
}
public class CustomLogProvider : ILoggerProvider
{
private readonly Func<string, LogLevel, bool> _filter;
private readonly IHttpContextAccessor _accessor;
private readonly ApplicationDbContext_context;
public CustomLogProvider(Func<string, LogLevel, bool> filter, IHttpContextAccessor accessor, ApplicationDbContext context)
{
_filter = filter;
_accessor = accessor;
_context = context;
// IF I USE THE variable _context in this place of code the applicationDbContext is available
// and so the behaviour is right
//if (_context != null)
//{
// Cliente cl = new Cliente();
// cl.codiceFiscale = "ALFA";
//
// _context.Add(cl);
// _context.SaveChanges();
//}
}
public ILogger CreateLogger(string categoryName)
{
// In this part of code there is the strange behaviour
// _context is different by null, but when I use _context
// the lifetime of service ApplicationDbContext is END
if (_context != null)
{
Cliente cl = new Cliente();
cl.codiceFiscale = "CCC";
_context.Add(cl);
_context.SaveChanges();
}
return new CustomLogger(categoryName, _filter, _accessor, _context);
}
public void Dispose()
{
//base.Dispose();
}
}
// THE ERROR IS IN THIS CLASS
public class CustomLogger : ILogger
{
private string _categoryName;
private Func<string, LogLevel, bool> _filter;
private readonly IHttpContextAccessor _accessor;
private readonly GestionaleOfficinaContext _context;
public CustomLogger(string categoryName, Func<string, LogLevel, bool> filter, IHttpContextAccessor accessor, GestionaleOfficinaContext context)
{
_categoryName = categoryName;
_filter = filter;
_accessor = accessor;
_context = context;
}
public IDisposable BeginScope<TState>(TState state)
{
return null;
}
public bool IsEnabled(LogLevel logLevel)
{
return (_filter == null || _filter(_categoryName, logLevel));
}
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func<TState, Exception, string> formatter)
{
if (!IsEnabled(logLevel))
{
return;
}
if (formatter == null)
{
throw new ArgumentNullException(nameof(formatter));
}
var message = formatter(state, exception);
if (string.IsNullOrEmpty(message))
{
return;
}
message = $"{ logLevel }: {message}";
// your implementation
}
}