Вы можете ввести все, что вам нужно, в метод Configure
.Вы уже добавили его в коллекцию сервисов со следующей строкой:
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
Поэтому все, что вам нужно сделать, это добавить его в список аргументов метода, подобного следующему:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, IHttpContextAccessor accessor)
{
// make use of it here
}
В качестве отступления: я также хотел бы отметить, что это немного пахнет кодом, когда вы вручную создаете экземпляр вашего DbContext
внутри вашего статического вспомогательного класса, когда вы используете внедрение зависимостей.
Обновление в ответ на комментарий
Чтобы немного привести в порядок вещи, я бы начал с изменения вашего запуска, чтобы настроить DbContext примерно так:
public class Startup
{
private readonly IConfiguration configuration;
public Startup(IConfiguration configuration)
{
this.configuration = configuration;
}
public void ConfigureServices(IServiceCollection services)
{
// register other things here...
services.AddDbContext<DataContext>(o => o.UseSqlServer(
config.GetConnectionString("MyConnectionString") // from appsettings.json
));
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
// set up app here...
}
}
Затем вы можете удалить метод .GetOptions()
из MyDbContext
и изменить конструктор на:
public MyDbContext(DbContextOptions<MyDbContext> options, IHttpContextAccessor httpContextAccessor)
: base(options)
{
_httpContextAccessor = httpContextAccessor;
}
Затем вы вставите экземпляр MyDbContext
в любой класс, которому требуется доступ к нему.,Проблема в том, что (насколько мне известно) DI плохо работает со статическими классами / методами, и вы используете метод расширения в HttpResponse
для регистрации вашей ошибки.
По моему мнению, было бы лучше создать класс, который будет отвечать за регистрацию ошибки с зависимостью от вашего MyDbContext
и вставлять ее в метод Configure
:
public class ErrorLogger
{
private MyDataContext db;
public ErrorLogger(MyDataContext db) => this.db = db;
public void LogError(IExceptionHandlerFeature error)
{
Log log = new Log();
log.Message = error.Error.Message;
UnitOfWork uow = new UnitOfWork(this.db);
uow.LogRepo.AddOrUpdate(log);
await uow.CompleteAsync(false);
}
}
Зарегистрируйте его в контейнере DI, как вы это делаете с другими вещами, а затем введите его в Configure
вместо средства доступа HTTP:
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ErrorLogger logger)
{
app.UseExceptionHandler(builder => builder.Run(async context =>
{
var error = context.Features.Get<IExceptionHandlerFeature>();
logger.LogError(error);
await context.Response.WriteAsync(error.Error.Message);
}));
}
Я не проверял это и не знаком с .UseExceptionHandler(...)
, поскольку я использую информацию о приложении для регистрации исключений и т. Д. (Посмотрите на это, если вы его не видели).Одна вещь, о которой нужно знать, это область ваших зависимостей;ваш DbContext будет Scoped
по умолчанию (и я думаю, вы должны оставить его таким), что означает, что вы не можете внедрить его в Singleton
объектов.