Я пытаюсь вставить ApplicationDbcontext в iLogger.
Когда я использую _context variable
внутри CustomLoggerProvider
или CustomLoggerExtension
, это работа .
Когда программное обеспечение CreateLogger
создает экземпляр CustomLogger
, у меня возникает проблема с ApplicationDbContext
, когда я использую переменную _context
для доступа к базе данных, приложение вылетает, а нене работает .
Ниже приведен журнал ошибок:
System.ObjectDisposedException HResult = 0x80131622 Messaggio = Невозможно получить доступ к удаленному объекту. Распространенной причиной этой ошибки является удаление контекста, который был разрешен путем внедрения зависимости, а затем попытка использовать тот же экземпляр контекста в другом месте вашего приложения. Это может произойти, если вы вызываете Dispose () для контекста или заключаете контекст в оператор using. Если вы используете внедрение зависимостей, вы должны позволить контейнеру внедрения зависимостей позаботиться об удалении экземпляров контекста.
Origine = Microsoft.EntityFrameworkCore Стек delal Analisi: в Microsoft.EntityFrameworkCore.DbContext.CheckDisposed () в Microsoft.EntityFrameworkCore.DbContext.Add [TEntity] (сущность TEntity)
в Microsoft.EntityFrameworkCore.Internal.InternalDbSet 1.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, исключение исключения, Func 3
formatter, List
1 & исключения, TState & state)
я думаю, что этопроблема жизненного цикла службы.
Кто-нибудь знает решение?
Startup.cs:
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);
}
}
CustomLogger.cs:
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
}
}