SharpArchitecture の VB.Net 変換での StructureMap 実装の問題
-
23-09-2019 - |
質問
私は 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 / の