2011-01-09 61 views
4

的兩個不同的實例在過去的兩天裏,我盡力去學習一些有關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行爲非常像第一個。我希望它使用一個具體的單個實例,並希望將它連接到不同的數據庫,以調用與不同的ConnectionSettings進行連接。

的問題是:雖然我敢肯定這是somewhow可能,(我最初的想法是註冊ExampleClass中具有替代構造函數參數),其實我是想做到這一點無需註冊ExampleClass中。這可能涉及更多配置,但我不知道如何去做。

所以,基本上,它歸結爲這樣一個問題: 我如何configurate的的ObjectFactory的方式,自動裝配總是調用與對象數據庫1的構造爲第一了IDatabase參數和對象的Database2的第二個(如果有是嗎?)

回答

2

你可以使用一個RegistrationConvention和命名實例第二連接。考慮下面的quick'n'dirty代碼:

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

這基本上正是我想要的。我認爲有人必須指出我註冊公約的方向。我可以從那裏開始工作。 StructureMap是一個強大的工具,但它的文檔缺少像一個大方向。 – Lambda 2011-01-09 15:26:01

相關問題