首页 > 解决方案 > 统一处理数据库上下文的正确方法

问题描述

我正在使用统一和依赖注入,目前,我对连接的处理有点困惑。

我将举一个例子,希望我能正确解释:)

我有一个使用服务的控制器:

public class CompaniesController : IDatabaseController
    {
        private readonly ICompaniesService _companiesService;
        public CompaniesController(ICompaniesService companiesService)
        {
         _companiesService = companiesService;
        }
    }

并且该服务注册到 UnityConfig 为:

container.RegisterType<ICompaniesService, CompaniesService>(new HierarchicalLifetimeManager());

*** 我读到如果我使用 IDisposable,那么 HierarchicalLifetimeManager 是强制性的。

实现接口的服务(我知道也可以注入数据库连接,但由于超出问题范围的原因请忽略它)是这样的:

public class CompaniesService : ICompaniesService
    {
        private readonly DatabaseContext _db = Helpers.GetDatabaseContextForRequest();

        /// <summary>
        /// Returns all employee of a company
        /// </summary>
        /// <param name="company_id">The id of the company</param>
        /// <returns>A collection of EmployeeDAP</returns>
        public IEnumerable<EmployeeDAP> GetCompanyEmployees(int company_id)
        {
            var employees = CompaniesRepository.GetCompanyEmployees(company_id);
            return employees;
        }
}

问题来了。我是否也应该实现服务的 IDisposable 接口并处理数据库连接,还是 GC 来清理混乱?

如果我必须手动处理连接,我应该使用 Dispose Pattern 还是

public void Dispose()
        {
            ((IDisposable)_db).Dispose();
        }

足够了?

提前致谢

更新:

辅助方法如下:

try
            {
                DatabaseContext db = (DatabaseContext)getRequestValue(name);
                if (db == null || !db.Database.Exists())
                {
                    db = new DatabaseContext();
                    setDatabaseContextForRequest(db, name);
                }
                return db;
            }
            catch (Exception)
            {
                return new DatabaseContext();
            }

其中 new DatabaseContext 继承自 EF 的 DbContext。

标签: c#.netasp.net-mvc-5unity-containeridisposable

解决方案


我认为让服务来处理DatabaseContext是给服务过多的责任。

我会将DatabaseContext配置从Helpers类移动到 Unity,使用PerRequestLifetimeManager.
使用 Unity 作为生命周期管理器,您将获得DatabaseContext跨越 HTTP 请求的 a,将 HTTP 请求生命周期近似为DatabaseContext.

这种方法将允许您避免让服务拥有DatabaseContext生命周期的所有权,将所有清理逻辑和所有权保留在 Unity 容器中。此外,您将能够DatabaseContext在单个请求中在服务之间安全地共享实例,因为DatabaseContext它仅在请求结束时被释放。

最后,请记住,一旦您丢弃了某些东西,您就无法再次使用它,因此您必须改进Helpers.GetDatabaseContextForRequest()以重新创建DatabaseContext它是否已被丢弃。


推荐阅读