Castle Windsor - 如何解析使用抽象工厂模式创建的接口

时间:2017-09-06 15:47:54

标签: vb.net castle-windsor

我正在使用抽象工厂模式来实例化对象。我只为客户端分配了一个类(公共类)来实例化 一个对象和该对象具有实例化其他对象的方法(仅对该程序集的Friend类)。

现在我想实现Castle-Windsor来解析我的界面。我对接口的所有对象创建逻辑都位于我的Public类中。

如何使用具有相同返回类型接口的方法的对象来解析我的接口。

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个类库项目和1个UI项目。

2 个答案:

答案 0 :(得分:0)

我在阅读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期间注入依赖关系。 (要求财产上的公共设定者)
  2. 为Main创建一个构造函数,将IDependency1和IDependency2作为参数。然后Windsor在Main的实例创建期间传递依赖项(您必须在构造函数中分配属性)
  3. 如果有帮助我可以为你提供我所说的C#代码。

答案 1 :(得分:0)

在对此进行一些调查之后,我发现通过实现XML配置,我可以解决我的依赖关系。

通过这种方式,我仍然可以将我的班级作为“内部或朋友”保持在课程库中。我只允许封装的类在我的客户端外部可见。

有了这个,我不必更改我的类的访问修饰符。我发现了一些其他方法也没有XML配置,但这些更改需要将我的类修饰符更改为“公共”。但我不想将这些类暴露给客户端。

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>