我有.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);
}
以及原因的连接字符串应在配置中,请参见教程。