gpt4 book ai didi

c# - 具有同一接口(interface)的两个不同实例的 StructureMap Autowiring

转载 作者:行者123 更新时间:2023-11-30 12:35:51 25 4
gpt4 key购买 nike

这两天,我以自己的一个老项目作为具体实现的例子,努力学习了一些关于StructureMap的知识。我试图尽可能地简化我的问题。虽然我将在 vb.net 中发布我的示例,但使用 C# 示例的答案也可以。

该项目包含一个名为 IDatabase 的接口(interface),它可以将自身连接到数据库。重要部分如下所示。

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 调用 Connect。

问题是:虽然我很确定这在某种程度上是可能的(我最初的想法是使用替代构造函数参数注册 ExampleClass),但我实际上想在不注册 ExampleClass 的情况下进行。这可能涉及更多配置,但我不知道该怎么做。

所以,基本上,归结为这个问题:我如何配置 ObjectFactory,使 Autowiring 始终为第一个 IDatabase 参数调用带有对象 Database1 的构造函数,为第二个 IDatabase 参数调用对象 Database2(如果有的话?)

最佳答案

您可以为第二个连接使用 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

你会明白的。

关于c# - 具有同一接口(interface)的两个不同实例的 StructureMap Autowiring ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4637235/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com