Problema Implementazione StructureMap in VB.Net Conversione di SharpArchitecture
-
23-09-2019 - |
Domanda
Io lavoro in un ambiente VB.Net e sono state recentemente con il compito di creare un ambiente MVC da utilizzare come base su cui lavorare. Ho deciso di convertire l'ultima release SharpArchitecture (3 ° trimestre 2009) in VB, che nel complesso è andato bene dopo un po 'di strapparsi i capelli. Mi sono imbattuto in un problema con il Castello di Windsor, dove la mia interfaccia repository personalizzati (vive nel progetto core / dominio) che era di riferimento nel costruttore del mio controller test non è stato sempre iniettato con la concreta attuazione (dal progetto di dati). Mi ha colpito un muro di mattoni con questo modo sostanzialmente deciso di passare fuori Castello di Windsor per StructureMap.
Credo di aver implementato questo male come tutto viene compilato e corre e il mio controller corse ok quando si fa riferimento un'interfaccia repository personalizzato. Sembra ora che ho / o non posso ora impostare il mio interfacce generiche correttamente (spero che questo ha un senso per quanto io sono nuovo a tutto questo). Quando uso IRepository (Of T) (volerlo da iniettare con un'implementazione concreta di Repository (di tipo)) nel costruttore regolatore sto ottenendo il seguente errore di runtime:
"Codice di eccezione StructureMap: 202 No default grado definito per PluginFamily SharpArch.Core.PersistenceSupport.IRepository`1 [[DebtRemedy.Core.Page, DebtRemedy.Core, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = null]], SharpArch.Core, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = b5f559ae0ac4e006"
Qui sono i miei brani di codice che sto usando (il mio progetto si chiama DebtRemedy).
La mia StructureMap classe registro
Public Class DefaultRegistry
Inherits Registry
Public Sub New()
''//Generic Repositories
AddGenericRepositories()
''//Custom Repositories
AddCustomRepositories()
''//Application Services
AddApplicationServices()
''//Validator
[For](GetType(IValidator)).Use(GetType(Validator))
End Sub
Private Sub AddGenericRepositories()
''//ForRequestedType(GetType(IRepository(Of ))).TheDefaultIsConcreteType(GetType(Repository(Of )))
[For](GetType(IEntityDuplicateChecker)).Use(GetType(EntityDuplicateChecker))
[For](GetType(IRepository(Of ))).Use(GetType(Repository(Of )))
[For](GetType(INHibernateRepository(Of ))).Use(GetType(NHibernateRepository(Of )))
[For](GetType(IRepositoryWithTypedId(Of ,))).Use(GetType(RepositoryWithTypedId(Of ,)))
[For](GetType(INHibernateRepositoryWithTypedId(Of ,))).Use(GetType(NHibernateRepositoryWithTypedId(Of ,)))
End Sub
Private Sub AddCustomRepositories()
Scan(AddressOf SetupCustomRepositories)
End Sub
Private Shared Sub SetupCustomRepositories(ByVal y As IAssemblyScanner)
y.Assembly("DebtRemedy.Core")
y.Assembly("DebtRemedy.Data")
y.WithDefaultConventions()
End Sub
Private Sub AddApplicationServices()
Scan(AddressOf SetupApplicationServices)
End Sub
Private Shared Sub SetupApplicationServices(ByVal y As IAssemblyScanner)
y.Assembly("DebtRemedy.ApplicationServices")
y.With(New FirstInterfaceConvention)
End Sub
End Class
Public Class FirstInterfaceConvention
Implements ITypeScanner
Public Sub Process(ByVal type As Type, ByVal graph As PluginGraph) Implements ITypeScanner.Process
If Not IsConcrete(type) Then
Exit Sub
End If
''//only works on concrete types
Dim firstinterface = type.GetInterfaces().FirstOrDefault()
''//grabs first interface
If firstinterface IsNot Nothing Then
graph.AddType(firstinterface, type)
Else
''//registers type
''//adds concrete types with no interfaces
graph.AddType(type)
End If
End Sub
End Class
Ho provato sia ForRequestedType (che credo sia ora sconsigliato) E PER. IRepository (Of T) vive in SharpArch.Core.PersistenceSupport. Repository (Of T) vive a SharpArch.Data.NHibernate.
La mia classe ServiceLocator
Public Class StructureMapServiceLocator
Inherits ServiceLocatorImplBase
Private container As IContainer
Public Sub New(ByVal container As IContainer)
Me.container = container
End Sub
Protected Overloads Overrides Function DoGetInstance(ByVal serviceType As Type, ByVal key As String) As Object
Return If(String.IsNullOrEmpty(key), container.GetInstance(serviceType), container.GetInstance(serviceType, key))
End Function
Protected Overloads Overrides Function DoGetAllInstances(ByVal serviceType As Type) As IEnumerable(Of Object)
Dim objList As New List(Of Object)
For Each obj As Object In container.GetAllInstances(serviceType)
objList.Add(obj)
Next
Return objList
End Function
End Class
La mia classe ControllerFactory
Public Class ServiceLocatorControllerFactory
Inherits DefaultControllerFactory
Protected Overloads Overrides Function GetControllerInstance(ByVal requestContext As RequestContext, ByVal controllerType As Type) As IController
If controllerType Is Nothing Then
Return Nothing
End If
Try
Return TryCast(ObjectFactory.GetInstance(controllerType), Controller)
Catch generatedExceptionName As StructureMapException
System.Diagnostics.Debug.WriteLine(ObjectFactory.WhatDoIHave())
Throw
End Try
End Function
End Class
La roba inizializzazione nel mio Global.asax
Dim container As IContainer = New Container(New DefaultRegistry)
ControllerBuilder.Current.SetControllerFactory(New ServiceLocatorControllerFactory())
ServiceLocator.SetLocatorProvider(Function() New StructureMapServiceLocator(container))
Il mio controller di test
Public Class DataCaptureController
Inherits BaseController
Private ReadOnly clientRepository As IClientRepository()
Private ReadOnly pageRepository As IRepository(Of Page)
Public Sub New(ByVal clientRepository As IClientRepository(), ByVal pageRepository As IRepository(Of Page))
Check.Require(clientRepository IsNot Nothing, "clientRepository may not be null")
Check.Require(pageRepository IsNot Nothing, "pageRepository may not be null")
Me.clientRepository = clientRepository
Me.pageRepository = pageRepository
End Sub
Function Index() As ActionResult
Return View()
End Function
È possibile che questo funziona bene quando prendo tutto ciò a che fare con la pageRepository che è IRepository (Of T).
Qualsiasi aiuto con questo sarebbe molto apprezzato.
Nessuna soluzione corretta
Altri suggerimenti
Ho avuto un problema simile ieri con un'istanza IRepository (Of MyEntity).
ho dovuto y.ConnectImplementationsToTypesClosing(GetType(IRepository(Of )))
stato nel mio delegato di scansione per rendere StructureMap mappa tipi generici per la loro attuazione.
In questo modo:
Private Shared Sub SetupCustomRepositories(ByVal y As IAssemblyScanner)
y.Assembly("DebtRemedy.Core")
y.Assembly("DebtRemedy.Data")
y.WithDefaultConventions()
y.ConnectImplementationsToTypesClosing(GetType(Of ));
End Sub
Assicurarsi che si sta creando un unico contenitore.
ho anche convertito un progetto C # dal Castello di Windsor a StructureMap. Il progetto originale CW a base di un'istanza un contenitore in Application_Start () (progetto MVC2) e lo passò in giro per la configurazione. Ho mantenuto lo stesso approccio senza pensare, un po 'quando si traducono dallo spagnolo all'inglese letteralmente, ed è altrettanto male. :)
Quello che è successo è che ho finito per la creazione di un secondo contenitore SM. contenitore di StructureMap è statico, e quindi c'è sempre un "in background". Se nuove fino un contenitore, in realtà si crea una seconda, contenitore indipendente. se non si sta attenti, si finisce a volte utilizzando uno, a volte l'altro, e ottenere una piaga di "No istanza predefinita" errori in vari punti quando si sa che è definito ..
Il modo in cui mi sono imbattuto è che ho finito per riempire il programma WhatDoIHave () chiama, che è stato fortunato perché ho notato che a volte ho visto un contenitore configurato (il secondo) e, a volte ho visto quello statico (la prima ), che non era stato configurato. Diversi nomi GUID è stato il giveaway.
Controlla se lo stesso sta accadendo nel codice VB.
Non che familiarità con questo, ma sembra che non può essere registrato con il contenitore o perché il resolver è avido potrebbe scegliere un costruttore che non ha voci registrate. Il seguente URL sembra molto simile allo stesso problema dare un'occhiata ... http://learningbyfailing.com / 2010/02 / StructureMap-eccezioni-no-default-instance-definita-per-pluginfamily-iformsauthentication /