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 /

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top