Castle Windsor - 如何解析使用抽象工厂模式创建的接口
Castle Windsor - How to resolve interfaces created using abstract factory pattern
我正在使用抽象工厂模式来实例化对象。而我只分配了一个class(publicclass)给客户端实例化
一个对象和该对象具有实例化其他对象的方法(Friend class 仅适用于该程序集)。
现在我想实现 Castle-Windsor 来解析我的接口。我对接口的所有对象创建逻辑都在我的 Public class.
中
如何使用具有相同 return 接口类型方法的对象解析我的接口。
BE 界面 ->
Public Interface IDependency1
Property DoSomething As String
End Interface
Public Interface IDependency2
Property DoSomething2 As String
End Interface
Public Interface IDependencyAll
Readonly Property Dependency1() As IDependency1
Function Dependency2() As IDependency2
End Interface
BL 实现 ->
Friend Class Dependency1
Implements IDependency1
Private newPropertyValue As String = "Test"
Public Property DoSomething() As String Implements IDependency1.DoSomething
Get
Return newPropertyValue
End Get
Set(ByVal value As String)
newPropertyValue = value
End Set
End Property
End Class
Friend Class Dependency2
Inherits rbASE
Implements IDependency2
Private newPropertyValue As String = "Test"
Public Property DoSomething2() As String Implements IDependency2.DoSomething2
Get
Return newPropertyValue
End Get
Set(ByVal value As String)
newPropertyValue = value
End Set
End Property
End Class
Public Class Main
Implements IDependencyAll
Public Readonly Property Dependency1() As IDependency1 Implements IDependencyAll.Dependency1
Get
Return New Dependency1
End Get
End Property
Public Function Dependency2() As IDependency2 Implements IDependencyAll.Dependency2
Return New Dependency2()
End Function
End Class
客户端 ->
Dim container = New WindsorContainer()
'container.Register(Castle.MicroKernel.Registration.Component.For(Of BE.Main1)())
'container.Register(Castle.MicroKernel.Registration.Component.For(Of BE.IDependency1)().ImplementedBy(Of BE.Dependency12)())
'container.Register(Castle.MicroKernel.Registration.Component.For(Of BE.IDependency2)().ImplementedBy(Of BE.Dependency22)())
'Dim mainThing = container.Resolve(Of BE.Main1)()
'mainThing.DoSomething()
Dim container1 = New WindsorContainer()
' container1.Register(Classes.FromAssemblyNamed("BE").Pick.WithService.DefaultInterfaces.LifestyleTransient)
container1.Register(Classes.FromAssemblyNamed("BL").BasedOn(GetType(IDependencyAll)).WithService.Base.LifestyleTransient)
'container1.Register(Classes.FromAssemblyNamed("BL").BasedOn(GetType(IDependency1)).WithService.Base.LifestyleTransient)
' container1.Register(Castle.MicroKernel.Registration.Component.For(Of BE.IDependencyAll)().ImplementedBy(Of BL.Main)())
Dim answer As String = "not resolved properluy"
Dim IcaseController As IDependencyAll = container1.Resolve(GetType(IDependencyAll))
Dim p = IcaseController.CreateBI(Of IDependency1)()
answer = p.DoSomething
'Dim p = IcaseController.
Label1.Text = answer
它有 2 个 class 库项目和 1 个 UI 项目。
我在阅读 VB 代码时遇到了一些问题,但如果我理解正确的话,你的意思就是这个
public interfaces
IDependency1
IDependency2
IDependencyAll (provides access to IDependency1 and IDependency2)
internal componenets
Dependency1 implementing IDependency1
Dependency2 implementing IDependency2
public components
Main implementing IDependencyAll
所以你会有两个选择
- 允许属性注入。 Windsor 然后在解析 Main 的过程中注入依赖项。 (需要 public setter 在 属性 上)
- 为 Main 创建一个构造函数,将您的 IDependency1 和 IDependency2 作为参数。 Windsor 然后在 Main 的实例创建期间传递依赖项(您必须从构造函数中分配属性)
如果有帮助,我可以为您提供我的意思的 C# 代码。
对此做了一些调查后,我发现通过实施 XML 配置我可以解决我的依赖关系。
这样我仍然可以将我的 class 作为 "Internal or Friend " 保存到 class 图书馆。我只允许封装的 class 在外部对我的客户可见。
有了这个,我不必更改我的 classes.I 的访问修饰符发现了一些其他方法也没有 XML 配置,但这些更改需要我的 class 修饰符被更改作为 "Public"。但我不想将那些 class 暴露给客户。
BE 代码
Public Interface IDependency1
Property DoSomething As String
End Interface
Public Interface IDependency2
Readonly Property DoSomething2 As String
End Interface
BL码
Friend Class Dependency1
Implements IDependency1
Private newPropertyValue As String = "Test"
Public Property DoSomething() As String Implements IDependency1.DoSomething
Get
Return newPropertyValue
End Get
Set(ByVal value As String)
newPropertyValue = value
End Set
End Property
End Class
Imports BE
Friend Class Dependency2
Implements IDependency2
Private cc As String
Public Sub New(cons As String)
cc = cons
End Sub
Public readonly Property DoSomething2 As String Implements IDependency2.DoSomething2
Get
Return cc + "test"
End Get
End Property
End Class
Imports BE
Imports System.Reflection
Imports Castle.MicroKernel.Registration
Imports Castle.MicroKernel.Resolvers.SpecializedResolvers
Imports Castle.Windsor
Public Class MainRepo
Inherits rbASE
Implements IDependencyAll
Function Generate(Of T)(cons As String) As T Implements IDependencyAll.ResolveBL
Dim container = New WindsorContainer()
container.Kernel.Resolver.AddSubResolver(New ArrayResolver(container.Kernel))
container.Install(Castle.Windsor.Installer.Configuration.FromAppConfig())
Return container.Resolve(Of T)(New With {.cons = cons})
End Function
end class
这里是 UI 代码
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim container1 = New WindsorContainer()
' container1.Register(Classes.FromAssemblyNamed("BE").Pick.WithService.DefaultInterfaces.LifestyleTransient)
container1.Register(Classes.FromAssemblyNamed("BL").BasedOn(GetType(IDependencyAll)).WithService.Base.LifestyleTransient)
'container1.Register(Classes.FromAssemblyNamed("BL").BasedOn(GetType(IDependency1)).WithService.Base.LifestyleTransient)
' container1.Kernel.Resolver.AddSubResolver(New CustomArrayResolver(container1.Kernel, GetType(IDependencyAll())))
' container1.Register(Castle.MicroKernel.Registration.Component.For(Of BE.IDependencyAll)().ImplementedBy(Of BL.Main)())
Dim answer As String = "not resolved properluy"
Dim IcaseController As IDependencyAll = container1.Resolve(Of IDependencyAll)()
Dim p = IcaseController.ResolveBL(Of IDependency2)("test cons")
answer = p.DoSomething2
'Dim p = IcaseController.
Label1.Text = answer
' mainThing1.DoSomething()
End Sub
这是配置
<configuration>
<configSections>
<section name="castle" type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler, Castle.Windsor" />
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<castle>
<components>
<component id="Dependency1" service="BE.IDependency1, BE" type="BE.IDependency1, BE" />
<component id="Dependency2" service="BE.IDependency2, BE" type="BL.Dependency2, BL" />
</components>
</castle>
我正在使用抽象工厂模式来实例化对象。而我只分配了一个class(publicclass)给客户端实例化 一个对象和该对象具有实例化其他对象的方法(Friend class 仅适用于该程序集)。
现在我想实现 Castle-Windsor 来解析我的接口。我对接口的所有对象创建逻辑都在我的 Public class.
中如何使用具有相同 return 接口类型方法的对象解析我的接口。
BE 界面 ->
Public Interface IDependency1
Property DoSomething As String
End Interface
Public Interface IDependency2
Property DoSomething2 As String
End Interface
Public Interface IDependencyAll
Readonly Property Dependency1() As IDependency1
Function Dependency2() As IDependency2
End Interface
BL 实现 ->
Friend Class Dependency1
Implements IDependency1
Private newPropertyValue As String = "Test"
Public Property DoSomething() As String Implements IDependency1.DoSomething
Get
Return newPropertyValue
End Get
Set(ByVal value As String)
newPropertyValue = value
End Set
End Property
End Class
Friend Class Dependency2
Inherits rbASE
Implements IDependency2
Private newPropertyValue As String = "Test"
Public Property DoSomething2() As String Implements IDependency2.DoSomething2
Get
Return newPropertyValue
End Get
Set(ByVal value As String)
newPropertyValue = value
End Set
End Property
End Class
Public Class Main
Implements IDependencyAll
Public Readonly Property Dependency1() As IDependency1 Implements IDependencyAll.Dependency1
Get
Return New Dependency1
End Get
End Property
Public Function Dependency2() As IDependency2 Implements IDependencyAll.Dependency2
Return New Dependency2()
End Function
End Class
客户端 ->
Dim container = New WindsorContainer()
'container.Register(Castle.MicroKernel.Registration.Component.For(Of BE.Main1)())
'container.Register(Castle.MicroKernel.Registration.Component.For(Of BE.IDependency1)().ImplementedBy(Of BE.Dependency12)())
'container.Register(Castle.MicroKernel.Registration.Component.For(Of BE.IDependency2)().ImplementedBy(Of BE.Dependency22)())
'Dim mainThing = container.Resolve(Of BE.Main1)()
'mainThing.DoSomething()
Dim container1 = New WindsorContainer()
' container1.Register(Classes.FromAssemblyNamed("BE").Pick.WithService.DefaultInterfaces.LifestyleTransient)
container1.Register(Classes.FromAssemblyNamed("BL").BasedOn(GetType(IDependencyAll)).WithService.Base.LifestyleTransient)
'container1.Register(Classes.FromAssemblyNamed("BL").BasedOn(GetType(IDependency1)).WithService.Base.LifestyleTransient)
' container1.Register(Castle.MicroKernel.Registration.Component.For(Of BE.IDependencyAll)().ImplementedBy(Of BL.Main)())
Dim answer As String = "not resolved properluy"
Dim IcaseController As IDependencyAll = container1.Resolve(GetType(IDependencyAll))
Dim p = IcaseController.CreateBI(Of IDependency1)()
answer = p.DoSomething
'Dim p = IcaseController.
Label1.Text = answer
它有 2 个 class 库项目和 1 个 UI 项目。
我在阅读 VB 代码时遇到了一些问题,但如果我理解正确的话,你的意思就是这个
public interfaces
IDependency1
IDependency2
IDependencyAll (provides access to IDependency1 and IDependency2)
internal componenets
Dependency1 implementing IDependency1
Dependency2 implementing IDependency2
public components
Main implementing IDependencyAll
所以你会有两个选择
- 允许属性注入。 Windsor 然后在解析 Main 的过程中注入依赖项。 (需要 public setter 在 属性 上)
- 为 Main 创建一个构造函数,将您的 IDependency1 和 IDependency2 作为参数。 Windsor 然后在 Main 的实例创建期间传递依赖项(您必须从构造函数中分配属性)
如果有帮助,我可以为您提供我的意思的 C# 代码。
对此做了一些调查后,我发现通过实施 XML 配置我可以解决我的依赖关系。
这样我仍然可以将我的 class 作为 "Internal or Friend " 保存到 class 图书馆。我只允许封装的 class 在外部对我的客户可见。
有了这个,我不必更改我的 classes.I 的访问修饰符发现了一些其他方法也没有 XML 配置,但这些更改需要我的 class 修饰符被更改作为 "Public"。但我不想将那些 class 暴露给客户。
BE 代码
Public Interface IDependency1
Property DoSomething As String
End Interface
Public Interface IDependency2
Readonly Property DoSomething2 As String
End Interface
BL码
Friend Class Dependency1
Implements IDependency1
Private newPropertyValue As String = "Test"
Public Property DoSomething() As String Implements IDependency1.DoSomething
Get
Return newPropertyValue
End Get
Set(ByVal value As String)
newPropertyValue = value
End Set
End Property
End Class
Imports BE
Friend Class Dependency2
Implements IDependency2
Private cc As String
Public Sub New(cons As String)
cc = cons
End Sub
Public readonly Property DoSomething2 As String Implements IDependency2.DoSomething2
Get
Return cc + "test"
End Get
End Property
End Class
Imports BE
Imports System.Reflection
Imports Castle.MicroKernel.Registration
Imports Castle.MicroKernel.Resolvers.SpecializedResolvers
Imports Castle.Windsor
Public Class MainRepo
Inherits rbASE
Implements IDependencyAll
Function Generate(Of T)(cons As String) As T Implements IDependencyAll.ResolveBL
Dim container = New WindsorContainer()
container.Kernel.Resolver.AddSubResolver(New ArrayResolver(container.Kernel))
container.Install(Castle.Windsor.Installer.Configuration.FromAppConfig())
Return container.Resolve(Of T)(New With {.cons = cons})
End Function
end class
这里是 UI 代码
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim container1 = New WindsorContainer()
' container1.Register(Classes.FromAssemblyNamed("BE").Pick.WithService.DefaultInterfaces.LifestyleTransient)
container1.Register(Classes.FromAssemblyNamed("BL").BasedOn(GetType(IDependencyAll)).WithService.Base.LifestyleTransient)
'container1.Register(Classes.FromAssemblyNamed("BL").BasedOn(GetType(IDependency1)).WithService.Base.LifestyleTransient)
' container1.Kernel.Resolver.AddSubResolver(New CustomArrayResolver(container1.Kernel, GetType(IDependencyAll())))
' container1.Register(Castle.MicroKernel.Registration.Component.For(Of BE.IDependencyAll)().ImplementedBy(Of BL.Main)())
Dim answer As String = "not resolved properluy"
Dim IcaseController As IDependencyAll = container1.Resolve(Of IDependencyAll)()
Dim p = IcaseController.ResolveBL(Of IDependency2)("test cons")
answer = p.DoSomething2
'Dim p = IcaseController.
Label1.Text = answer
' mainThing1.DoSomething()
End Sub
这是配置
<configuration>
<configSections>
<section name="castle" type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler, Castle.Windsor" />
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
<castle>
<components>
<component id="Dependency1" service="BE.IDependency1, BE" type="BE.IDependency1, BE" />
<component id="Dependency2" service="BE.IDependency2, BE" type="BL.Dependency2, BL" />
</components>
</castle>