2011-01-09 2 views
4

지난 2 일 동안 구형 프로젝트를 콘크리트 구현 예제로 사용하여 StructureMap에 대해 배웠습니다. 나는 가능한 한 내 질문을 단순화하려고 노력했다. vb.net에 예제를 게시 할 예정이지만 C#의 예제를 사용한 응답도 괜찮습니다.StructureMap 동일한 인터페이스의 두 개의 다른 인스턴스로 자동 연결

프로젝트에는 자체 데이터베이스에 연결하는 IDatabase라는 인터페이스가 포함되어 있습니다. 중요한 부분은 이렇게 보입니다.

Public Interface IDatabase 
    Function Connect(ByVal ConnectionSettings As ConnectionSettings) As Boolean 
    ReadOnly Property ConnectionOpen As Boolean 
    [... more functions...] 
End Interface 

Public Class MSSQLConnection 
    Implements IDatabase 
    Public Function Connect(ByVal ConnectionSettings As ConnectionSettings) As Boolean Implements IDatabase.Connect 

     [... Implementation ...] 

    End Function 

[... more implementations...] 
End Class 

ConnectionSettings는 데이터베이스에 연결하는 데 필요한 모든 정보가있는 구조입니다.

데이터베이스 연결을 한 번 열고 프로젝트의 모든 단일 연결에 사용하려는 경우 ObjectFactory에 인스턴스를 등록합니다.

dim foo = ObjectFactory.GetInstance(Of MSSQLConnection)() 
dim bar as ConnectionSettings 
foo.connect(bar) 
ObjectFactory.Configure(Sub(x) x.For(Of IDatabase).Use(foo)) 

이 부분까지는 모든 것이 매력처럼 작동합니다. 이제는 두 번째 데이터베이스에 연결하기 때문에 IDatabase의 추가 인스턴스가 필요한 클래스가 생겼습니다.

Public Class ExampleClass 
Public Sub New(ByVal SameOldDatabase as IDatabase, ByVal NewDatabase as IDatabase) 
[...] Magic happens here [...] 
End Sub 
End Class 

이 두 번째 IDatabase는 첫 번째 IDatabase와 매우 유사하게 동작합니다. 구체적이고 단일 인스턴스를 사용하고 다른 ConnectionSettings를 사용하여 Connect를 호출하는 다른 데이터베이스에 연결하려고합니다.

문제는 : 대체로 가능하다고 생각하지만 (실제로는 ExampleClass를 다른 생성자 인수로 등록하는 것이 었습니다.) 실제로 ExampleClass를 등록하지 않고이 작업을 수행하려고합니다. 이것은 아마도 더 많은 구성을 포함하지만, 나는 그것을 어떻게하는지 모른다.

기본적으로이 질문은 다음과 같습니다. 자동 와이어 링은 첫 번째 IDatabase 매개 변수에는 Database1 개체가 있고 두 번째 IDatabase 매개 변수에는 Object2 개체가있는 생성자를 항상 호출하는 방식으로 ObjectFactory를 구성하는 방법은 무엇입니까? 하나입니까?)

답변

2

두 번째 연결에는 RegistrationConvention와 명명 된 인스턴스를 사용할 수 있습니다. 다음과 같은 빠른 코드를 고려하십시오.

Imports StructureMap.Graph 
Imports StructureMap.Configuration.DSL 
Imports StructureMap 

Public Module Module1 

    Public Interface IDatabase 
     Property ConString As String 
    End Interface 

    Public Class MSSQLConnection 
     Implements IDatabase 
     Public Property ConString() As String Implements IDatabase.ConString 
    End Class 

    Public Class ExampleClass 
     Public Sub New(ByVal SameOldDatabase As IDatabase, ByVal NewDatabase As IDatabase) 
      Console.WriteLine(SameOldDatabase.ConString) 
      Console.WriteLine(NewDatabase.ConString) 
     End Sub 
    End Class 

    Public Class SecondDatabaseConstructorIsAnotherOne 
     Implements IRegistrationConvention 

     Public Sub Process(ByVal type As Type, ByVal registry As Registry) Implements IRegistrationConvention.Process 
      Dim ctor = type.GetConstructors().FirstOrDefault(Function(c) c.GetParameters().Where(Function(p) p.ParameterType = GetType(IDatabase)).Count = 2) 
      If Not ctor Is Nothing Then 

       Dim parameter = New List(Of Object) 

       Dim second = False 

       For Each o In ctor.GetParameters() 
        If o.ParameterType = GetType(IDatabase) AndAlso second Then 
         parameter.Add(ObjectFactory.GetNamedInstance(Of IDatabase)("secondDB")) 
        Else 
         If o.ParameterType = GetType(IDatabase) Then second = True 
         parameter.Add(ObjectFactory.GetInstance(o.ParameterType)) 
        End If 
       Next 

       registry.For(type).Use(Function(context) Activator.CreateInstance(type, parameter.ToArray())) 

      End If 
     End Sub 

    End Class 

    Sub Main() 

     Dim con1 = New MSSQLConnection() With {.ConString = "ConnectToFirstDatabase"} 
     Dim con2 = New MSSQLConnection() With {.ConString = "ConnectToSecondDatabase"} 

     ObjectFactory.Initialize(Sub(init) 
            init.For(Of IDatabase).Use(con1) 
            init.For(Of IDatabase).Add(con2).Named("secondDB") 
           End Sub) 

     ObjectFactory.Configure(Sub(config) 
            config.Scan(Sub(scan) 
                scan.TheCallingAssembly() 
                scan.Convention(Of SecondDatabaseConstructorIsAnotherOne)() 
               End Sub) 
           End Sub) 

     ObjectFactory.GetInstance(Of ExampleClass)() 
     Console.ReadLine() 
    End Sub 

End Module 

아이디어를 얻을 수 있습니다.

+0

그건 기본적으로 정확히 원하는 것입니다. 나는 누군가가 단지 RegistrationConventions의 방향으로 나를 지적해야만한다고 생각한다. 거기서부터 일할 수 있습니다. StructureMap은 강력한 도구이지만 문서에는 일반적인 방향과 같은 것이 없습니다. – Lambda