質問

私は VB.Net 環境で働いており、最近、作業のベースとして使用する MVC 環境を作成する任務を与えられました。私は、SharpArchitecture の最新リリース (2009 年第 3 四半期) を VB に変換することにしました。少し苦労したものの、全体的にはうまくいきました。Castle Windsor で、テスト コントローラーのコンストラクターで参照されているカスタム リポジトリ インターフェイス (コア/ドメイン プロジェクトに存在する) が、(データ プロジェクトからの) 具体的な実装で注入されないという問題に遭遇しました。これでは壁にぶつかったので、基本的に Castle Windsor を StructureMap に切り替えることにしました。

すべてがコンパイルされて実行され、カスタム リポジトリ インターフェイスを参照するときにコントローラーが正常に実行されたため、これは正常に実装できたと思います。現在、汎用インターフェイスを適切にセットアップできている、またはセットアップできないようです (これについては初めてなので、これが理解できることを願っています)。コントローラー コンストラクターで IRepository(Of T) (Repository(Of Type) の具体的な実装で挿入することを希望) を使用すると、次のランタイム エラーが発生します。

「StructureMap 例外コード:202 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、カルチャー=中立、PublicKeyToken=b5f559ae0ac4e006"

以下は私が使用しているコードの抜粋です (私のプロジェクトは DebtRemedy と呼ばれています)。

私のストラクチャマップレジストリクラス

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

ForRequestedType(現在は非推奨になっていると思います)とForの両方を試しました。IRepository(Of T) は SharpArch.Core.PersistenceSupport にあります。リポジトリ(Of T) は SharpArch.Data.NHibernate にあります。

私のサービスロケータークラス

    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

私のコントローラーファクトリークラス

    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

私のglobal.asaxの初期化のもの

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

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

私のテストコントローラー

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

IRepository(Of T)であるpageRepositoryに関係するものをすべて取り出すと、上記は正常に機能します。

ご協力いただければ幸いです。

正しい解決策はありません

他のヒント

私は(MyEntityの)IRepositoryをインスタンス化して、昨日同様の問題があった。

私はのStructureMapは、その実施にジェネリック型をマップするために私のスキャンデリゲートに状態y.ConnectImplementationsToTypesClosing(GetType(IRepository(Of )))に持っていた。

このように:

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

あなたが唯一のコンテナを作成していることを確認します。

私はまたのStructureMapに城ウィンザーからC#プロジェクトを変換します。元CWベースのプロジェクトは、のApplication_Startコンテナ()(MVC2プロジェクト)をインスタンス化し、設定のために周りにそれを渡されました。私はあなたがlitterallyスペイン語から英語に翻訳しちょっととき、考えずに同じアプローチを続け、それだけで悪いようです。 :)

何が起こった私は2番目SMコンテナを作成してしまったということです。 StructureMapのコンテナは、静的であり、そしてその一つは、「バックグラウンドで」常にあります。あなたは、コンテナを新しい場合は、実際には二、独立したコンテナを作成します。あなたが注意されていない場合、あなたは時には他のものを、使用して終了し、あなたはそれが定義されています知っているとき、「Noデフォルトインスタンス」の様々な点での誤差の疫病を取得..

私はそれに出くわした道は、私は時々それを指摘し、私が構成された容器(第2)を見て、時々私は、静的の1を見たので、私は幸運だっWhatDoIHave()の呼び出し、とポイ捨て私のコードを終わったということである(第一)、どのように構成されていませんでした。異なるGUID名のプレゼントだった。

同じことがあなたのVBのコードで何が起こっているかどうかをチェックします。

この精通していること、それがコンテナに登録されていないか、リゾルバは貪欲であるため、それが登録された項目を持っていないではないコンストラクタを選択する可能性がありますように

はないが、それが見えます。同じ問題に非常に似て、次のURLのルックスは見てみましょう... http://learningbyfailing.com / 2010/02 /のStructureMap-例外なしデフォルト・インスタンス定義-FOR-pluginfamily-iformsauthentication /

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top