Windsor MixIn 是单例吗?

发布于 2024-07-16 12:23:18 字数 561 浏览 7 评论 0原文

我有一个 MixIn 需要某种状态才能运行。

我将其注册为这样......

    container.Register(Component.For(Of ICat) _
                        .ImplementedBy(Of Cat) _
                        .LifeStyle.Transient _
                        .Proxy.MixIns(New MyMixin()))

当我调用container.Resolve(ICat)时,我得到ICat的代理,它也实现了IMixin。

但是,如果我再次调用 container.Resolve(of ICat),我会获得 ICat 的新代理,但 MyMixin 是相同的实例。 (这是有道理的,因为我没有告诉容器任何创建 IMixin 的方法)

因此,IMixin 是一个单例,即使组件的生活方式是瞬态的。

我如何通过 Fluent Interface 告诉 Windsor 为组件创建一个新的 MyMixIn 实例?

I have a MixIn that requires some state to operate.

I am registering it as so..

    container.Register(Component.For(Of ICat) _
                        .ImplementedBy(Of Cat) _
                        .LifeStyle.Transient _
                        .Proxy.MixIns(New MyMixin()))

When I call container.Resolve(of ICat), I get back a proxy for ICat, which also implements IMixin.

However, if I call container.Resolve(of ICat) again, I get a new proxy for ICat, but MyMixin is the SAME instance. (Which makes sense because I didn't tell the container any way to create IMixin)

So, IMixin is a Singleton, even though the Component's lifestyle is Transient.

How can I tell Windsor, though the Fluent Interface, to create a new Instance of MyMixIn for the component?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

一刻暧昧 2024-07-23 12:23:18

我想我解决了这个问题。

我没有使用 Proxy.Mixins,而是创建了一个自定义 Activator()

Public Class MixInActivator(Of T)
   Inherits Castle.MicroKernel.ComponentActivator.DefaultComponentActivator

  Public Sub New(ByVal model As Castle.Core.ComponentModel, ByVal kernel As Castle.MicroKernel.IKernel, ByVal OnCreation As Castle.MicroKernel.ComponentInstanceDelegate, ByVal OnDestruction As Castle.MicroKernel.ComponentInstanceDelegate)
    MyBase.New(model, kernel, OnCreation, OnDestruction)
  End Sub

  Protected Overrides Function InternalCreate(ByVal context As Castle.MicroKernel.CreationContext) As Object

    Dim obj As Object = MyBase.InternalCreate(context)
    If GetType(T).IsAssignableFrom(obj.GetType) = False Then
        Dim options As New Castle.DynamicProxy.ProxyGenerationOptions
        Dim gen As New Castle.DynamicProxy.ProxyGenerator
        options.AddMixinInstance(Kernel.Resolve(Of T))
        obj = gen.CreateInterfaceProxyWithTarget(Model.Service, obj, options)
    End If
    Return obj
 End Function
End Class

所以现在,组件是这样注册的

 container.Register(Component.For(Of ICat) _
                     .ImplementedBy(Of Cat) _
                     .LifeStyle.Is(Castle.Core.LifestyleType.Transient) _
                     .Activator(Of MixInActivator(Of IMixin)))

并且 IMixin 注册如下

container.Register(Component.For(Of IMixin) _
                       .ImplementedBy(Of MyMixin) _
                       .LifeStyle.Is(Castle.Core.LifestyleType.Transient) _
                       .Named("MyMixin"))

I think I resolved this.

Instead of using Proxy.Mixins, I created a custom Activator()

Public Class MixInActivator(Of T)
   Inherits Castle.MicroKernel.ComponentActivator.DefaultComponentActivator

  Public Sub New(ByVal model As Castle.Core.ComponentModel, ByVal kernel As Castle.MicroKernel.IKernel, ByVal OnCreation As Castle.MicroKernel.ComponentInstanceDelegate, ByVal OnDestruction As Castle.MicroKernel.ComponentInstanceDelegate)
    MyBase.New(model, kernel, OnCreation, OnDestruction)
  End Sub

  Protected Overrides Function InternalCreate(ByVal context As Castle.MicroKernel.CreationContext) As Object

    Dim obj As Object = MyBase.InternalCreate(context)
    If GetType(T).IsAssignableFrom(obj.GetType) = False Then
        Dim options As New Castle.DynamicProxy.ProxyGenerationOptions
        Dim gen As New Castle.DynamicProxy.ProxyGenerator
        options.AddMixinInstance(Kernel.Resolve(Of T))
        obj = gen.CreateInterfaceProxyWithTarget(Model.Service, obj, options)
    End If
    Return obj
 End Function
End Class

So now, the component is registered like this

 container.Register(Component.For(Of ICat) _
                     .ImplementedBy(Of Cat) _
                     .LifeStyle.Is(Castle.Core.LifestyleType.Transient) _
                     .Activator(Of MixInActivator(Of IMixin)))

And IMixin is registered as follows

container.Register(Component.For(Of IMixin) _
                       .ImplementedBy(Of MyMixin) _
                       .LifeStyle.Is(Castle.Core.LifestyleType.Transient) _
                       .Named("MyMixin"))
[浮城] 2024-07-23 12:23:18

我不确定它是如何冒泡到 Windsor 的,但在 DynamicProxy 级别,每个代理类型都有 mixin 实例。 因此,如果您要创建自己的 mixin 实例,则可能每次都会生成新的代理类型。 要避免这种情况,请在混合类型中覆盖 Equals 和 GetHashCode。

但我可能不正确,所以你可能需要先确定一下。

I'm not sure how it bubbles up to Windsor, but at DynamicProxy level, there's mixin Instance per proxy type. So if you're creating yourself mixin instances, you may be also each time be generating a new proxy type. To circumvent this, override Equals and GetHashCode in your mixed in type.

I may however not be right, so you may want to make sure first.

蛮可爱 2024-07-23 12:23:18

如果您使用 Transcient 生活方式注册 mixin,它将为每个组件创建一个新实例:

container.Register(
    Component.For<ICat>().ImplementedBy<Cat>()
        .LifestyleTransient()
        .Proxy.MixIns(m => m.Component("mixin")),
    Component.For<MyMixin>().LifestyleTransient().Named("mixin")
);

If you register the mixin with transcient lifestyle, it will create a new instance for each component:

container.Register(
    Component.For<ICat>().ImplementedBy<Cat>()
        .LifestyleTransient()
        .Proxy.MixIns(m => m.Component("mixin")),
    Component.For<MyMixin>().LifestyleTransient().Named("mixin")
);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文