如何使用 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());
        }

更新:临时存储库没有解决问题,这是我的一个错误 - 我只是忘记了我正在查看的记录实际上已提交到数据库,因此没有调用创建操作。 我的错误,抱歉。

如何使用 ContextFactory 和存储库正确注入 DbContext for WebAPI

正如用户 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的所有帮助。