Использование ASP.NET MVC, Linq To SQL и StructureMap, вызывающих DataContext для кэширования данных - PullRequest
5 голосов
/ 25 марта 2010

Начну с того, что расскажу о настройке своего проекта:

  • ASP.NET MVC 1.0
  • StructureMap 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

Все отлично работает с загрузкой зависимостей, но у меня проблемы с классом DCSDataContext, созданным классами Linq2SQL.

У меня есть форма, которая отправляет на страницу сведений (/ Summary / Details), которая загружает некоторые данные из SQL. Затем у меня есть кнопка, которая открывает диалоговое окно в JQuery, которое заполняет диалог от запроса до (/ 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

Может кто-нибудь помочь, пожалуйста?

1 Ответ

5 голосов
/ 25 марта 2010

Получил ответ от Джереми Миллера в группе Google StructureMap:

Легкие деньги, вы создаете экземпляр вашего объекта DataContext -yourself- при регистрации, что фактически делает его единым целым во всей экосистеме StructureMap. Этот код:

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

Необходимо определить DataContext, используя -deferred- выполнение вместо использования предварительно созданного «New DCSDataContext ()»

Если бы вы были в C # (потому что я не знаю синтаксис VB), вы бы сделали:

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

Я запустил это через конвертер C # в VB, и он дал мне это:

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

Что отлично работает!

...