2010-03-25 4 views
5

Je vais commencer en disant ma configuration du projet:En utilisant ASP.NET MVC, LINQ to SQL et StructureMap provoquant DataContext aux données du cache

  • ASP.NET MVC 1.0
  • StructureMap 2.6.1
  • VB

J'ai créé une classe bootstrapper montré ici:

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 

J'ai créé une usine de contrôleur montré ici:

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 

J'ai modifié le Global.asax.vb comme indiqué ici:

... 
    Sub Application_Start() 

     RegisterRoutes(RouteTable.Routes) 

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

    End Sub 
... 

J'ai ajouté un fichier de registre de la carte de la structure à chacun de mes trois projets: DCS, DCS.Data et DCS.Services. Voici le registre 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 

Tout fonctionne très bien pour autant que le chargement des dependecies, mais je vais avoir des problèmes avec la classe DCSDataContext qui a été genereated par classes linq2sql.

J'ai un formulaire qui poste sur une page de détails (/ Summary/Details), qui charge dans certaines données de SQL. J'ai alors un bouton qui ouvre une boîte de dialogue dans JQuery, qui remplit la boîte de dialogue d'une requête à (/ Operator/Modify). Dans la boîte de dialogue, le formulaire a une zone de liste déroulante et un bouton OK qui permet à l'utilisateur de modifier le nom de l'opérateur. En cliquant sur OK, le formulaire est posté dans (/ Operator/Modify) et envoyé via les couches de service et de référentiel de mon programme et met à jour l'enregistrement dans la base de données. Ensuite, le RedirectToAction est appelé pour renvoyer l'utilisateur à la page de détails (/ Summary/Details) où il y a un appel pour retirer les données de SQL, mettant à jour la vue des détails.

Tout fonctionne très bien, sauf que la vue détaillée n'affiche pas le nouvel opérateur sélectionné. Je peux parcourir le code et voir la classe DCSDataContext accessible pour mettre à jour l'opérateur (qui change réellement l'enregistrement de la base de données), mais lorsque l'on accède au DCSDataContext pour recharger les objets détails, il récupère l'ancienne valeur. Je suppose que StructureMap provoque non seulement la classe DCSDataContext mais aussi les données à mettre en cache?

J'ai également essayé d'ajouter ce qui suit au Global.asax, mais il termine juste s'écraser le programme me dit la DCSDataContext a été disposé ...

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

    StructureMap.ObjectFactory.ReleaseAndDisposeAllHttpScopedObjects() 

End Sub 

Quelqu'un peut-il s'il vous plaît aider?

Répondre

5

Vous avez cette réponse de retour de Jeremy Miller sur le groupe google StructureMap:

argent facile, vous créez une instance de votre DataContext objectera -yourself- dans l'enregistrement, ce qui de facto fait qu'un singleton tout au long l'écosystème StructureMap.

Ce code:

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

a besoin de définir le DataContext en utilisant l'exécution -deferred- plutôt que d'utiliser le "New DCSDataContext()" pré-construit

Si vous étiez en C# (parce que je ne connais pas la syntaxe VB), vous feriez:

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

j'ai couru ce à travers un C# convertisseur VB et il m'a donné ceci:

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

Ce qui fonctionne très bien!

+0

Comment est-ce que je donne le paramètre à() => nouveau DCSDataContext (paramètre), je veux que la création de paramater soit auto câblée, je ne veux pas créer et donner manuellement –

+0

@Sessiz Satt: J'avais fait ceci avec la chaîne de connexion propriété. J'avais tiré ma propriété de chaîne de connexion du fichier Web.Config et l'ai passée comme ceci ...() => nouveau DCSDataContext (ConfigurationManager.AppSettings ["Key"]) – Dragn1821

Questions connexes