【问题标题】:Using ASP.NET MVC, Linq To SQL, and StructureMap causing DataContext to cache data使用 ASP.NET MVC、Linq To SQL 和 StructureMap 导致 DataContext 缓存数据
【发布时间】:2011-01-31 21:18:37
【问题描述】:

我将首先介绍我的项目设置:

  • ASP.NET MVC 1.0
  • 结构图 2.6.1
  • VB

我创建了一个引导程序类,如下所示:

Imports StructureMap
Imports DCS.Data
Imports DCS.Services

Public Class BootStrapper

    Public Shared Sub ConfigureStructureMap()

        ObjectFactory.Initialize(AddressOf StructureMapRegistry)

    End Sub

    Private Shared Sub StructureMapRegistry(ByVal x As IInitializationExpression)

        x.AddRegistry(New MainRegistry())
        x.AddRegistry(New DataRegistry())
        x.AddRegistry(New ServiceRegistry())
        x.Scan(AddressOf StructureMapScanner)

    End Sub

    Private Shared Sub StructureMapScanner(ByVal scanner As StructureMap.Graph.IAssemblyScanner)

        scanner.Assembly("DCS")
        scanner.Assembly("DCS.Data")
        scanner.Assembly("DCS.Services")
        scanner.WithDefaultConventions()

    End Sub

End Class

我已经创建了一个控制器工厂,如下所示:

Imports System.Web.Mvc
Imports StructureMap

Public Class StructureMapControllerFactory
    Inherits DefaultControllerFactory

    Protected Overrides Function GetControllerInstance(ByVal controllerType As System.Type) As System.Web.Mvc.IController

        Return ObjectFactory.GetInstance(controllerType)

    End Function

End Class

我已经修改了 Global.asax.vb,如下所示:

...
    Sub Application_Start()

        RegisterRoutes(RouteTable.Routes)

        'StructureMap
        BootStrapper.ConfigureStructureMap()
        ControllerBuilder.Current.SetControllerFactory(New StructureMapControllerFactory())

    End Sub
...

我为我的三个项目中的每一个都添加了一个结构映射注册表文件:DCS、DCS.Data 和 DCS.Services。这是 DCS.Data 注册表:

Imports StructureMap.Configuration.DSL

Public Class DataRegistry
    Inherits Registry

    Public Sub New()

        'Data Connections.
        [For](Of DCSDataContext)() _
            .HybridHttpOrThreadLocalScoped _
            .Use(New DCSDataContext())

        'Repositories.
        [For](Of IShiftRepository)() _
            .Use(Of ShiftRepository)()

        [For](Of IMachineRepository)() _
            .Use(Of MachineRepository)()

        [For](Of IShiftSummaryRepository)() _
            .Use(Of ShiftSummaryRepository)()

        [For](Of IOperatorRepository)() _
            .Use(Of OperatorRepository)()

        [For](Of IShiftSummaryJobRepository)() _
            .Use(Of ShiftSummaryJobRepository)()

    End Sub

End Class

就加载依赖项而言,一切都很好,但我遇到了由 Linq2SQL 类生成的 DCSDataContext 类的问题。

我有一个发布到详细信息页面 (/Summary/Details) 的表单,该表单从 SQL 加载一些数据。然后我有一个按钮,可以在 JQuery 中打开一个对话框,该对话框将对话框从请求填充到 (/Operator/Modify)。在对话框中,表单有一个组合框和一个允许用户更改操作员姓名的确定按钮。单击“确定”后,表单将发布到 (/Operator/Modify) 并通过我的程序的服务和存储库层发送,并更新数据库中的记录。然后,调用 RedirectToAction 将用户返回到详细信息页面(/Summary/Details),在此调用再次从 SQL 中提取数据,更新详细信息视图。

一切都很好,除了详细信息视图不显示选择的新运算符。我可以单步执行代码并查看正在访问的 DCSDataContext 类以更新运算符(这实际上会更改数据库记录),但是当访问 DCSDataContext 以重新加载详细信息对象时,它会拉入旧值。我猜 StructureMap 不仅会导致 DCSDataContext 类,还会导致数据被缓存?

我也尝试将以下内容添加到 Global.asax,但它最终导致程序崩溃,告诉我 DCSDataContext 已被处理...

Private Sub MvcApplication_EndRequest(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.EndRequest

   StructureMap.ObjectFactory.ReleaseAndDisposeAllHttpScopedObjects()

End Sub

有人可以帮忙吗?

【问题讨论】:

    标签: asp.net-mvc linq-to-sql caching structuremap datacontext


    【解决方案1】:

    在 StructureMap 谷歌组中收到了 Jeremy Miller 的回复:

    轻松赚钱,您正在注册中创建您的 DataContext 对象的实例 - 您自己 - 这实际上使该实例成为整个 StructureMap 生态系统中的单例。

    这段代码:

    'Data Connections. 
    [For](Of DCSDataContext)() _ 
        .HybridHttpOrThreadLocalScoped _ 
        .Use(New DCSDataContext()) 
    

    需要使用-deferred-执行来定义DataContext,而不是使用预建的“New DCSDataContext()”

    如果你在 C# 中(因为我不懂 VB 语法),你会这样做:

    For<DCSDataContext>().HybridHttpOrThreadLocalScoped().Use(() => new DCSDataContext()); 
    

    我通过一个 C# 到 VB 转换器运行它,它给了我这个:

    [For](Of DCSDataContext)() _
        .HybridHttpOrThreadLocalScoped _
        .Use(Function() New DCSDataContext())
    

    效果很好!

    【讨论】:

    • 如何给 () => new DCSDataContext(parameter) 提供参数,我希望参数的创建是自动连接的,我不想手动创建和提供
    • @Sessiz Satt:我使用连接字符串属性完成了这项工作。我从 Web.Config 文件中提取了我的连接字符串属性并像这样传递它... ()=>new DCSDataContext(ConfigurationManager.AppSettings["Key"])
    猜你喜欢
    • 2013-08-07
    • 1970-01-01
    • 2011-01-07
    • 2012-12-25
    • 1970-01-01
    • 2011-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多