【问题标题】:Linq: scoped DataContext, unit-of-work, repositoryLinq:作用域 DataContext、工作单元、存储库
【发布时间】:2011-11-17 15:20:53
【问题描述】:

我一直在研究 C# 中的工作单元和存储库模式。 AFAIK,DataContext 实现了工作单元模式,并可用于实现存储库接口。 DataContext 中缺少的最后一点是一种在预定义范围内全局共享此资源的方法。

我简要地将 NCommon 视为解决这个缺失部分的方法。您会分享您在 NCommon 方面的经验,或推荐其他解决方案吗?如果我误解了也请纠正我。谢谢。

【问题讨论】:

    标签: c# linq datacontext


    【解决方案1】:

    我一直以与 NHibernate 相同的方式使用 DataContext:使用静态方式获取它,并使用不同的存储方式来存储它。例如,对于基于 Web 的应用程序,它可以存储在 HttpContext.Current.Items 集合中,或者对于单元测试,它可以存储在 Call.Context 中。您何时创建实例以及何时关闭它取决于场景。同样,对于 Web,在应用程序的 Request_begin 和 Request_end 事件上执行此操作是有意义的。对于单元测试,可能是在设置和拆卸中。

    希望对你有帮助。

    编辑:这里有一些实现

    public abstract class DataContextProvider
    {
        public abstract DataContext GetCurrent();
        public abstract void OpenNew();
    
        public void CloseCurrent()
        {
            var current = GetCurrent();
            current.Dispose();
        }
    }
    

    在您的数据上下文中添加以下内容:

    public static DataContextProvider Provider { private get; set; }
    
    public static DataContext Current { get { return Provider.GetCurrent(); } }
    

    网页版:

    在你的 web 项目中你放了这个类:

    public class WebDataContextProvider : DataContextProvider 
    {
        private const string Key = "WebDataContextProvider.DataContext";
    
        public override DataContext GetCurrent()
        {
            return (DataContext)HttpContext.Current.Items[Key];
        }
    
        public override void OpenNew()
        {
            HttpContext.Current.Items[Key] = new DataContext();
        }
    }
    

    在你的 global.asax 中:

    你添加一个 WebDataContextProvider 类型的字段:

    WebDataContextProvider dataContextProvider = new WebDataContextProvider();
    

    你覆盖了应用程序启动事件:

    DataContext.Provider = dataContextProvider;
    

    在您提出的请求开始事件中:

    dataContextProvider.OpenNew();
    

    在你的请求结束事件中你放了:

    dataContextProvider.CloseCurrent();
    

    用于测试

    对于您的测试项目,您可以遵循相同的逻辑,但创建一个 TestDataContextProvider,例如:

    public class WebDataContextProvider : DataContextProvider 
    {
        [ThreadStatic]
        private static DataContext Current;
    
        public override DataContext GetCurrent()
        {
            return Current;
        }
    
        public override void OpenNew()
        {
            Current = new DataContext();
        }
    }
    

    并在您的 SetUp 和 TearDown 方法中打开和关闭数据上下文,并在 Test 或 TestFixtureSetUp 的构造函数中配置“当前提供者”

    希望对你有帮助。

    【讨论】:

    • 当您需要在特定任务的对象之间共享此 DataContext 时会发生什么?
    • 您使用了一种控制反转。您可以使用框架或将 DataContext 作为包含任务的类的构造函数的参数。 O 你可以“静态地”访问它,比如 DataContext.Current (从定义的上下文中返回它)
    • 谁维护 DataContext.Current?
    • 视情况而定。在 web 上,它通常会放在 httpmodule 或 global.asax 中,使用 Request_Begin 和 Request_End 事件在每个请求中设置它。在测试中,它可以在 SetUp 中创建并在 TearDown 中处理。
    • 我需要一个管理 DataContext.Current 的库。例如,一个函数可以指定它是需要一个新的 DataContext 还是从调用者那里继承当前的 DataContext。然后管理器管理沿执行路径创建的 DataContext 堆栈。
    猜你喜欢
    • 1970-01-01
    • 2011-01-02
    • 2013-04-23
    • 2016-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-10
    相关资源
    最近更新 更多