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

所以你会有两个选择

  1. 允许属性注入。 Windsor 然后在解析 Main 的过程中注入依赖项。 (需要 public setter 在 属性 上)
  2. 为 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>