Pergunta

Eu trabalho em um ambiente VB.Net e recentemente recebi a tarefa de criar um ambiente MVC para usar como base de trabalho.Decidi converter o último lançamento do SharpArchitecture (terceiro trimestre de 2009) em VB, que no geral funcionou bem depois de alguns puxões de cabelo.Me deparei com um problema com o Castle Windsor onde minha interface de repositório customizada (vive no projeto núcleo/domínio) que era referência no construtor do meu controlador de teste não estava sendo injetada com a implementação concreta (do projeto de dados).Eu bati em uma parede de tijolos com isso, então basicamente decidi trocar o Castle Windsor pelo StructureMap.

Acho que implementei isso corretamente, pois tudo é compilado e executado e meu controlador funcionou bem ao fazer referência a uma interface de repositório personalizada.Parece agora que não consigo/ou não consigo configurar minhas interfaces genéricas corretamente (espero que isso faça sentido, já que sou novo em tudo isso).Quando uso IRepository(Of T) (desejando que ele seja injetado com uma implementação concreta de Repository(Of Type)) no construtor do controlador, estou recebendo o seguinte erro de tempo de execução:

"Código de exceção do StructureMap:202 Nenhuma instância padrão definida para 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, Cultura=neutro, PublicKeyToken=b5f559ae0ac4e006"

Aqui estão meus trechos de código que estou usando (meu projeto se chama DebtRemedy).

Minha classe de registro do 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

Eu tentei ForRequestedType (que acho que agora está obsoleto) e For.IRepository (Of T) reside em SharpArch.Core.PersistenceSupport.O repositório (Of T) reside em SharpArch.Data.NHibernate.

Minha 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

Minha 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

O material de inicialização no meu global.asax

Dim container As IContainer = New Container(New DefaultRegistry)
ControllerBuilder.Current.SetControllerFactory(New ServiceLocatorControllerFactory())

ServiceLocator.SetLocatorProvider(Function() New StructureMapServiceLocator(container))

Meu controlador de teste

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

O acima funciona bem quando retiro tudo o que tem a ver com o pageRepository que é IRepository (Of T).

Qualquer ajuda com isso seria muito apreciado.

Nenhuma solução correta

Outras dicas

Ontem tive um problema semelhante ao instantar o irepository (da myentidade).

Eu tive que afirmar y.ConnectImplementationsToTypesClosing(GetType(IRepository(Of ))) No meu delegado de varredura para fazer o mapa de estruturasp Tipos genéricos para sua implementação.

Assim:

Private Shared Sub SetupCustomRepositories(ByVal y As IAssemblyScanner)
    y.Assembly("DebtRemedy.Core")
    y.Assembly("DebtRemedy.Data")
    y.WithDefaultConventions()
    y.ConnectImplementationsToTypesClosing(GetType(Of ));
End Sub

Certifique-se de criar apenas um contêiner.

Também converti um projeto C# de Castle Windsor para StructureMap.O projeto original baseado em CW instanciou um Container em Application_Start() (projeto MVC2) e o passou para configuração.Mantive a mesma abordagem sem pensar, mais ou menos quando você traduz literalmente do espanhol para o inglês, e é igualmente ruim.:)

O que aconteceu é que acabei criando um segundo contêiner SM.O contêiner do StructureMap é estático e, portanto, sempre há um "em segundo plano".Se você criar um contêiner novo, na verdade criará um segundo contêiner independente.se você não tomar cuidado, às vezes acaba usando um, às vezes o outro, e recebe uma praga de erros "Sem instância padrão" em vários pontos quando sabe que está definido.

A maneira como descobri isso é que acabei enchendo meu código com chamadas WhatDoIHave(), o que foi uma sorte porque notei que às vezes via um contêiner configurado (o segundo) e às vezes via o estático (o primeiro), que não havia sido configurado.Nomes diferentes de GUID foram a oferta.

Verifique se o mesmo está acontecendo no seu código VB.

Não está tão familiarizado com isso, mas parece que pode não estar registrado no contêiner ou porque o resolvedor é ganancioso, pode escolher um construtor que não tenha itens registrados. O URL a seguir parece muito parecido com o mesmo problema, dê uma olhada ...http://learningbyfailing.com/2010/02/structureMap-exception-no-default-instance-defined-for-pluginfamily-iformsauthentication/

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top