从.NET Core 2.1中的DBContext访问服务



我有.net core 2.1 webAPI项目。我创建基本dbcontext,名称为 DataContext.cs。我想通过IAuditHelper启动DataContext。当项目启动时,我可以从我的 startup.cs

设置AuditHelper

但是,在项目启动并执行SaveChangesAsync方法之后,是无效的。如何从DataContext获得Autitherper?(我知道,如果我在DataContext构造函数中注入iaudithelper,那么我可以接受。但是,在这种情况下,datacontext想要iaudithelper到处都是。

datacontext.cs

 public class DataContext : DbContext,IDataContext
 {
     public IAuditHelper AuditHelper { get; set; }
     public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = default(CancellationToken))
     {
         auditHelper.LogMyChangesToDatabase()
         return (await base.SaveChangesAsync(true, cancellationToken));
     }
 }

idatacontext.cs

public interface IDataContext : IDisposable
{
    IAuditHelper AuditHelper{ get; set; }
    Task<int> SaveChangesAsync(CancellationToken cancellationToken);
    Task<int> SaveChangesWithoutAuditAsync(CancellationToken cancellationToken);
}

universitydbcontext.cs

 public class UniversityDbContext: DataContext
 {      
    override protected void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
      optionsBuilder.UseSqlServer("server=.; database=.; user id=.; 
            password=.;");
    }
    public UniversityDbContext() : base()
    {
    }
 }

startup.cs

public void ConfigureServices(IServiceCollection services)
{
    services.AddScoped<IAuditHelper, AuditHelper>();
    services.AddScoped<IDataContext, DataContext>();
    services.AddScoped<DataContext, UniversityDbContext>();
    services.AddDbContext<UniversityDbContext>();
       
    var sp = services.BuildServiceProvider();
    var dataContext = sp.GetService<IDataContext>();
    dataContext.AuditHelper = sp.GetService<IAuditHelper>();
}

asp.net核心依赖注入不支持财产注入,您可以如下所示,而是将依赖项注入构造函数。另一个选择是使用支持属性注入的容器,例如Unity或AutoFac。

public class DataContext : DbContext, IDataContext
{
    public DataContext(IAuditHelper auditHelper, DbContextOptions options)
        : base(options)
    {
        AuditHelper = auditHelper;
    }
    public IAuditHelper AuditHelper { get; private set; }
    public override Task<int> SaveChangesAsync(CancellationToken cancellationToken = default(CancellationToken))
    {
        AuditHelper.LogMyChangesToDatabase();
        return base.SaveChangesAsync(true, cancellationToken);
    }
    ...
}
public interface IDataContext : IDisposable
{
    IAuditHelper AuditHelper { get; }
    Task<int> SaveChangesAsync(CancellationToken cancellationToken);
    ...
}
public class UniversityDbContext : DataContext
{
    public UniversityDbContext(IAuditHelper auditHelper, DbContextOptions options)
        : base(auditHelper, options)
    {
    }
}

我不太明白为什么您在idatacontext接口中需要Autithperper,我会将其保存在DataContext提交的私人中,不会公开它。

Autithelper类:

public class AuditHelper : IAuditHelper
{
    private readonly IHttpContextAccessor _httpContextAccessor;
    public AuditHelper(IHttpContextAccessor httpContextAccessor)
    {
        _httpContextAccessor = httpContextAccessor;
    }
    public void LogMyChangesToDatabase()
    {
        //_httpContextAccessor.HttpContext.
    }
}

在启动类中:

public class Startup
{
    ...
    public void ConfigureServices(IServiceCollection services)
    {
        ...
        services.AddHttpContextAccessor();
        services.AddDbContext<UniversityDbContext>(options
            => options.UseSqlServer("Server=(localdb)\mssqllocaldb;Database=TestUniversity;Trusted_Connection=True;MultipleActiveResultSets=true"));
        services.AddScoped<IAuditHelper, AuditHelper>();
        ...
    }
    ...
}

您可以在链接处找到范围的区别。

控制器:

public class SomeController : ControllerBase
{
    private readonly UniversityDbContext _context;
    public SomeController(UniversityDbContext context)
    {
        _context = context;
    }
    [HttpPost]
    public async Task Post([FromBody] string value)
    {
        ...
        await _context.SaveChangesAsync();
    }
}

我还建议关注点击并更改logmychangestodatabase:

    public async Task LogMyChangesToDatabase()
    {
        //_httpContextAccessor.HttpContext.
        //await 
    }

Savechangesasync将相应:

    public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = default(CancellationToken))
    {
        await AuditHelper.LogMyChangesToDatabase();
        return await base.SaveChangesAsync(true, cancellationToken);
    }

以及原因的连接字符串应在配置中,请参见教程。

最新更新