C# 如何获取Castle Windsor中某些依赖项的当前实例化实例列表?

C# 如何获取Castle Windsor中某些依赖项的当前实例化实例列表?,c#,castle-windsor,ioc-container,C#,Castle Windsor,Ioc Container,假设我有一个组件Bar,它执行Foo,并在实现IFooConsumer接口的所有服务上通知调用Foo方法 我可以这样写Bar class Bar { public Bar(IEnumerable<IFooConsumer> fooConsumers) { ... } public void Foo() { // foo-ing foreach (var f in _fooConsumers) f.FooHappened();

假设我有一个组件
Bar
,它执行
Foo
,并在实现
IFooConsumer
接口的所有服务上通知调用
Foo
方法

我可以这样写
Bar

class Bar
{
    public Bar(IEnumerable<IFooConsumer> fooConsumers) { ... }

    public void Foo()
    {
        // foo-ing
        foreach (var f in _fooConsumers) f.FooHappened();
    }
}
类栏
{
公共酒吧(IEnumerable fooConsumers){…}
公共图书馆
{
//富英
foreach(var f in_fooConsumers)f.fooOccurs();
}
}
它会起作用,但实例化
Bar
将实例化所有可能的
IFooConsumer
s。如果我只需要通知发生
Foo
时存在的
IFooConsumer
s,该怎么办

有没有一种方法可以获取某种跟踪程序,它可以了解
IFooConsumer
的所有实例化实例


我可能可以通过订阅
IWindsorContainer.Kernel.ComponentCreated
自己编写一个,但我对是否存在类似的东西感兴趣?或者也许有其他方法可以解决我的问题?

我认为,把关键放在知道哪些对象在温莎城堡实例化并不是最好的方法;您肯定需要访问一些容器方法,这样做会将您的组件链接到Castle,这是不应该发生的

我建议改为创建一个组件
IBouncer
。该组件将作为单例注入所有
IFooConsumer
,在创建和处置时调用它(处置是一个选项,您可以使用其他方法)


您可以创建一个简单的工具,如下图所示,它将在每次实例化组件时进行事件注册。下面的代码用于将Winsor与Caliburn.Micro一起使用。这也将确保事件被取消注册,否则将导致奇怪的行为。在您的情况下,我不会让Bar直接向所有类触发事件,而是使用单例组件(如下面的IEventAggregator)向多个类触发事件。这也将确保事件被取消注册,否则将导致奇怪的行为。在代码中,从IHandle派生的每个类都将接收事件。您可以根据自己的需要进行更改

如果你有任何问题,请告诉我

class EventRegistrationFacility : AbstractFacility
{
    private IEventAggregator _eventAggregator;
    protected override void Init()
    {
        Kernel.ComponentCreated += ComponentCreated;
        Kernel.ComponentDestroyed += ComponentDestroyed;
    }

    void ComponentCreated(Castle.Core.ComponentModel model, object instance)
    {
        if (!(instance is IHandle)) return;
        if (_eventAggregator == null) _eventAggregator = Kernel.Resolve<IEventAggregator>();
        _eventAggregator.Subscribe(instance);
    }

    void ComponentDestroyed(Castle.Core.ComponentModel model, object instance)
    {
        if (!(instance is IHandle)) return;
        if (_eventAggregator == null) return;
        _eventAggregator.Unsubscribe(instance);
    }

}
class EventRegistrationFacility:AbstractFacility
{
私人事件聚合器;
受保护的重写void Init()
{
Kernel.ComponentCreated+=ComponentCreated;
Kernel.ComponentDestroyed+=ComponentDestroyed;
}
创建的无效组件(Castle.Core.ComponentModel模型,对象实例)
{
如果(!(实例为IHandle))返回;
如果(_eventAggregator==null)_eventAggregator=Kernel.Resolve();
_订阅(实例);
}
无效组件已销毁(Castle.Core.ComponentModel模型,对象实例)
{
如果(!(实例为IHandle))返回;
if(_eventAggregator==null)返回;
_eventAggregator.Unsubscribe(实例);
}
}
==编辑====

将其与Sammy所述的bouncer相结合:

public interface IBouncer {
    IEnumerable<IFooConsumer> WhoIsInside {get;}
    void WelcomeTo(IFooConsumer consumer);
    void EscortOut(IFooConsumer consumer);
}

public class Bouncer {
    private IList<IFooConsumer> _inside {get;}
    void WelcomeTo(IFooConsumer consumer) {
        _inside.Add(consumer);
}
    void EscortOut(IFooConsumer consumer);
        _inside.Remove(consumer);
    }
    IEnumerable<IFooConsumer> WhoIsInside {
        get {
            return _inside;
        }
    }



public Consumer: IFooConsumer {
    FooHappened() {
        // Do something.
}
    // no need to implement constructor/dispose
}


class Bar
{
    public Bar(IBouncer bouncer) { ... }

    public void Foo()
    {
        // foo-ing ==> alernatively create a function on Bouncer that does this. And keep WhoIsInside private.
        foreach (var f in bouncer.WhoIsInside) f.FooHappened();
    }
}


class BouncerRegistrationFacility : AbstractFacility
{
    private IBouncer _bouncer
    protected override void Init()
    {
        Kernel.ComponentCreated += ComponentCreated;
        Kernel.ComponentDestroyed += ComponentDestroyed;
    }

    void ComponentCreated(Castle.Core.ComponentModel model, object instance)
    {
        if (!(instance is IFooConsumer)) return;
        if (_bouncer == null) _bouncer = Kernel.Resolve<IEventAggregator>();
        _bouncer.WelcomeTo(instance);
    }

    void ComponentDestroyed(Castle.Core.ComponentModel model, object instance)
    {
        if (!(instance is IFooConsumer)) return;
        if (_bouncer == null) return;
        _bouncer.EscortOut(instance);
    }
}
公共接口IBouncer{
IEnumerable WhoIsInside{get;}
void WelcomeTo(IFooConsumer);
无效护送(IFooConsumer-consumer);
}
公营保镖{
私有IList_在{get;}
void WelcomeTo(IFooConsumer){
_添加(消费者);
}
无效护送(IFooConsumer-consumer);
_内部。移除(消费者);
}
可数整体{
得到{
返回内部;
}
}
公共消费者:IFooConsumer{
foothapped(){
//做点什么。
}
//无需实现构造函数/处置
}
分类栏
{
公共酒吧(IBouncer bouncer){…}
公共图书馆
{
//foo-ing==>在Bouncer上创建一个函数来完成此操作,并将所有隐藏的内容保持为私有。
foreach(bouncer.WhoIsInside中的变量f)f.foocated();
}
}
类BouncerRegistrationFacility:AbstractFacility
{
私人保镖
受保护的重写void Init()
{
Kernel.ComponentCreated+=ComponentCreated;
Kernel.ComponentDestroyed+=ComponentDestroyed;
}
创建的无效组件(Castle.Core.ComponentModel模型,对象实例)
{
如果(!(实例为IFooConsumer))返回;
如果(_bouncer==null)_bouncer=Kernel.Resolve();
_bouncer.WelcomeTo(实例);
}
无效组件已销毁(Castle.Core.ComponentModel模型,对象实例)
{
如果(!(实例为IFooConsumer))返回;
如果(_bouncer==null)返回;
_保镖护送(实例);
}
}
尽管您需要更多的代码来编写该工具,但FooConsumers不需要自己注册/注销。由于注册码最初必须在所有文件中写入,因此它往往会重复。这样,订阅/取消订阅作为佣金/退役要求进行,只需处理一次


p.S.代码是用记事本编写的,可能包含编译错误。

我想说的是,您应该避免让对象事件的订阅者成为对象的依赖项。如果您试图通知事件的侦听器,则应该有一个单独的订户机制。例如,要将侦听器实例与
fooOccessed
事件关联,请在
Bar
上声明
fooHappendHandler
方法委托,并将其设置为侦听器上的方法。然后在
Foo()
内部调用
foocated(this)
,这将允许侦听器定义的代码执行。@moarboilerplate给定Castle Windsor的机制实现实际上是个问题。可以使用事件或类似事件的机制,但需要显式订阅/取消订阅以避免内存泄漏。集装箱已经在等待了
class EventRegistrationFacility : AbstractFacility
{
    private IEventAggregator _eventAggregator;
    protected override void Init()
    {
        Kernel.ComponentCreated += ComponentCreated;
        Kernel.ComponentDestroyed += ComponentDestroyed;
    }

    void ComponentCreated(Castle.Core.ComponentModel model, object instance)
    {
        if (!(instance is IHandle)) return;
        if (_eventAggregator == null) _eventAggregator = Kernel.Resolve<IEventAggregator>();
        _eventAggregator.Subscribe(instance);
    }

    void ComponentDestroyed(Castle.Core.ComponentModel model, object instance)
    {
        if (!(instance is IHandle)) return;
        if (_eventAggregator == null) return;
        _eventAggregator.Unsubscribe(instance);
    }

}
public interface IBouncer {
    IEnumerable<IFooConsumer> WhoIsInside {get;}
    void WelcomeTo(IFooConsumer consumer);
    void EscortOut(IFooConsumer consumer);
}

public class Bouncer {
    private IList<IFooConsumer> _inside {get;}
    void WelcomeTo(IFooConsumer consumer) {
        _inside.Add(consumer);
}
    void EscortOut(IFooConsumer consumer);
        _inside.Remove(consumer);
    }
    IEnumerable<IFooConsumer> WhoIsInside {
        get {
            return _inside;
        }
    }



public Consumer: IFooConsumer {
    FooHappened() {
        // Do something.
}
    // no need to implement constructor/dispose
}


class Bar
{
    public Bar(IBouncer bouncer) { ... }

    public void Foo()
    {
        // foo-ing ==> alernatively create a function on Bouncer that does this. And keep WhoIsInside private.
        foreach (var f in bouncer.WhoIsInside) f.FooHappened();
    }
}


class BouncerRegistrationFacility : AbstractFacility
{
    private IBouncer _bouncer
    protected override void Init()
    {
        Kernel.ComponentCreated += ComponentCreated;
        Kernel.ComponentDestroyed += ComponentDestroyed;
    }

    void ComponentCreated(Castle.Core.ComponentModel model, object instance)
    {
        if (!(instance is IFooConsumer)) return;
        if (_bouncer == null) _bouncer = Kernel.Resolve<IEventAggregator>();
        _bouncer.WelcomeTo(instance);
    }

    void ComponentDestroyed(Castle.Core.ComponentModel model, object instance)
    {
        if (!(instance is IFooConsumer)) return;
        if (_bouncer == null) return;
        _bouncer.EscortOut(instance);
    }
}