如何使用 ContextFactory 和存储库正确注入 DbContext for WebAPI
本文关键字:注入 DbContext for WebAPI 何使用 ContextFactory 存储 | 更新日期: 2023-09-27 18:33:08
我正在尝试在 Web API 背面为每个 Web 请求安全地注入存储库的数据库上下文。消费类调用存储库以检索对象,如果返回 null,则从不同的数据存储中获取对象并将其保存在数据库中,以便以后更快地访问。这意味着它正在尝试从数据库获取,然后执行操作,然后创建新记录。
目前我有这个存储库
public class OrganisationRepository : IOrganisationRepository
{
public Func<IOrganisationDomainDbContext> ContextFactory { get; set; }
public Organisation GetDetailByIdentifier(int id)
{
using (var context = ContextFactory.Invoke())
{
var org = context.Organisations.SingleOrDefault(x => x.Id == id);
return org;
}
}
public void Create(Organisation orgToCreate)
{
using (var context = ContextFactory.Invoke())
{
context.Organisations.Add(orgToCreate);
context.SaveChanges();
}
}
}
并且存储库以短暂的生活方式注入到消费类中。DbContext 是按 Web 请求注入的。
以前,存储库注入了单例生活方式,这种生活方式在"创建"操作中被破坏。
我的问题是,我是否通过使存储库瞬态来做廉价的黑客攻击?这会给我带来问题吗?如果是这样,我应该如何以不同的方式执行此操作?
编辑:有关更多信息,正在使用的DI容器是温莎城堡编辑:DI安装程序的相关部分
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(
Component.For<IOrganisationDomainDbContext>().ImplementedBy<OrganisationDomainDbContext>().LifeStyle.PerWebRequest,
Component.For<Func<IOrganisationDomainDbContext>>().Instance(container.Resolve<IOrganisationDomainDbContext>),
Component.For<IOrganisationRepository>().ImplementedBy<OrganisationRepository>().LifeStyle.Transient,
Classes.FromThisAssembly().BasedOn<ApiController>().LifestylePerWebRequest());
}
更新:临时存储库没有解决问题,这是我的一个错误 - 我只是忘记了我正在查看的记录实际上已提交到数据库,因此没有调用创建操作。 我的错误,抱歉。
正如用户 jbl 指出的那样,我不需要在上下文使用中使用使用块 - DI 容器会根据 Web 请求处理上下文。
这是现在的代码:
public class OrganisationRepository : IOrganisationRepository
{
public Func<IOrganisationDomainDbContext> ContextFactory { get; set; }
public Organisation GetDetailByIdentifier(int id)
{
var context = ContextFactory.Invoke()
var org = context.Organisations.SingleOrDefault(x => x.Id == id);
return org;
}
public void Create(Organisation orgToCreate)
{
var context = ContextFactory.Invoke();
context.Organisations.Add(orgToCreate);
context.SaveChanges();
}
}
和 DI 容器安装程序:
container.Register(
Component.For<IOrganisationDomainDbContext>().ImplementedBy<OrganisationDomainDbContext>().LifeStyle.PerWebRequest,
Component.For<Func<IOrganisationDomainDbContext>>().Instance(container.Resolve<IOrganisationDomainDbContext>),
Component.For<IOrganisationRepository>().ImplementedBy<OrganisationRepository>().LifeStyle.PerWebRequest,
Classes.FromThisAssembly().BasedOn<ApiController>().LifestylePerWebRequest());
希望这是正确的答案,调试显示上下文在每个 Web 请求后被处理,我没有遇到异常。感谢jbl和Mark Seeman的所有帮助。