使用通用存储库模式时,DatabaseContext 总是会重新初始化并且不会保持状态

DatabaseContext always got reinitialized and didn't keep states when using generic repository pattern

试图找出如何在我的应用程序上共享我的上下文的相同实例,但 DBContext 在每个失去其状态的请求中不断重新初始化。 我有一个 dbfactory 负责初始化我的上下文。

public class DbFactory: Disposable, IDbFactory
{
    GamaTaskDbContext dbContext;

    public GamaTaskDbContext Init()
    {
        return dbContext ?? (dbContext = new GamaTaskDbContext());
    }

    protected override void DisposeCore()
    {
        if (dbContext != null)
            dbContext.Dispose();
    }
}

我还有一个通用存储库 class,其中的问题是每个请求都会触发存储库构造函数并发现 dbContext 为空并重新初始化它,因此对于每个请求我都有新的上下文实例 class 这导致我当然无法删除实体,因为获取数据的上下文与试图删除它的上下文不同。

 public abstract class Repository<Tentity> where Tentity : class
{
    private  GamaTaskDbContext dataContext;
    private readonly IDbSet<Tentity> dbSet;


    protected IDbFactory DbFactory
    {
        get;
        private set;
    }
    protected GamaTaskDbContext DbContext
    {
        get { return dataContext ?? (dataContext = DbFactory.Init());}
    }
    public Repository(IDbFactory dbFactory)
    {
        DbFactory = dbFactory;
        dbSet = DbContext.Set<Tentity>();

    }

IOC 配置

      private static void SetAutofacContainer()
    {
        var builder = new ContainerBuilder();
        builder.RegisterControllers(Assembly.GetExecutingAssembly());
        builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().InstancePerRequest();
        builder.RegisterType<DbFactory>().As<IDbFactory>().InstancePerLifetimeScope();

        // Repositories
        builder.RegisterAssemblyTypes(typeof(CustomerRepository).Assembly)
            .Where(t => t.Name.EndsWith("Repository"))
            .AsImplementedInterfaces().InstancePerRequest();
        // Services
        builder.RegisterAssemblyTypes(typeof(CustomerService).Assembly)
           .Where(t => t.Name.EndsWith("Service"))
           .AsImplementedInterfaces().InstancePerRequest();

        builder.Register(c => new MapperConfiguration(cfg => {
            foreach (var profile in c.Resolve<IEnumerable<Profile>>())
            {
                cfg.AddProfile(profile);
            }
        })).AsSelf().SingleInstance();

        builder.Register(c => c.Resolve<MapperConfiguration>()
                 .CreateMapper(c.Resolve))
                 .As<IMapper>()
                 .InstancePerLifetimeScope();

        IContainer container = builder.Build();
        DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
    }

依赖注入只是调用者控制所有依赖项的模式。这不仅意味着调用者是决定每个接口使用哪个 class 的人,而且还决定注入对象的寿命。

反转控制容器不仅用于解决所有依赖关系,还用于确保在需要时创建新对象,并在适当的时候处理所有一次性对象。

必须具有特定生命周期的对象称为作用域对象。对于 Web 应用程序,生命周期范围通常是 HTTP 请求的持续时间。

在您的示例中,您试图既保持控制又让控制反转容器完成工作。让容器管理您的 dbcontext 的生命周期。通过这样做,它将在第一个 class 请求它作为依赖项时创建它,然后将相同的 dbContext 实例传递给所有其他需要它的 classes。

放下控制,万事大吉

因此我只需要这段代码:

public abstract class Repository<Tentity> where Tentity : class
{
    private  GamaTaskDbContext _dataContext;
    private readonly IDbSet<Tentity> dbSet;


    public Repository(GamaTaskDbContext dataContext)
    {
        _dataContext = dataContext;
        dbSet = _dataContext .Set<Tentity>();

    }
protected GamaTaskDbContext DbContext
{
    get { return _dataContext; }
}

然后这样注册:

builder.RegisterType<GamaTaskDbContext>().InstancePerLifetimeScope();

无需执行任何其他操作。

很少有您真正希望 DbContext 在多个 http 请求期间存在的情况。通常它只是伤害大于你的收获。