Lavoro in un ambiente VB.Net e recentemente mi è stato assegnato il compito di creare un ambiente MVC da utilizzare come base da cui lavorare. Ho deciso di convertire l'ultima versione di SharpArchitecture (Q3 2009) in VB, che nel complesso è andata bene dopo aver tirato un po 'di capelli. Mi sono imbattuto in un problema con Castle Windsor, in cui la mia interfaccia di repository personalizzata (che vive nel progetto core/dominio) di riferimento nel costruttore del mio controller di test non è stata iniettata con l'implementazione concreta (dal progetto di dati). Ho colpito un muro di mattoni con questo in modo sostanzialmente deciso di cambiare Castle Windsor per StructureMap.Problema Implementazione di StructureMap nella conversione VB.Net di SharpArchitecture
Penso di aver implementato questo ok in quanto tutto compila ed esegue e il mio controller ha funzionato bene quando fa riferimento a un'interfaccia repository personalizzata. Ora sembra che ho/o non posso ora configurare correttamente le mie interfacce generiche (spero che questo abbia senso per quanto io sia nuovo a tutto questo). Quando utilizzo IRepository (Of T) (volendo che venga iniettato con un'implementazione concreta di Repository (Of Type)) nel costruttore controller ricevo il seguente errore di runtime:
"StructureMap Codice eccezione: 202 No Default Istanza definita per PluginFamily SharpArch.Core.PersistenceSupport.IRepository`1 [[DebtRemedy.Core.Page, DebtRemedy.Core, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = null]], SharpArch.Core, Versione = 1.0.0.0 , Culture = neutro, PublicKeyToken = b5f559ae0ac4e006 "
Ecco i miei estratti di codice che sto utilizzando (il mio progetto si chiama DebtRemedy).
La mia classe registro StructureMap
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. L'IRepository (Of T) vive in SharpArch.Core.PersistenceSupport. Il repository (Of T) vive in 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))
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.
Purtroppo non posso aiutarti con il tuo problema ma è bello vedere che ci sono persone là fuori che sanno scrivere un buon codice VB . La maggior parte delle domande VB qui su Stack Overflow mi ha fatto disperare. –
IMHO si potrebbe davvero semplificare questa domanda - basta mostrare le linee di codice in cui si sta tentando di registrare i tipi che stanno fallendo, e impostare poche righe di codice cercando di ottenere un'istanza di quel tipo attraverso il contenitore o la fabbrica di oggetti . Se la registrazione non funziona, dovrebbe fallire allo stesso modo. –