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);
}
}