怎么在城堡里.从IHandler中获取组件对象
本文关键字:获取 组件 对象 IHandler 城堡 | 更新日期: 2023-09-27 18:17:14
我为Castle.Windsor创建了自定义设施。简而言之。我用我的自定义属性MyComponent标记组件类的一些属性。在这个工具中,我订阅了Kernel.ComponentRegistered。在组件注册时,我检查是否有任何组件的属性标记了该属性。如果是,我也使用该属性的值进行组件注册。问题是如何获得组件本身的对象当我有IHandler和字符串键的对象:
public class ComponentsSearcherFacility : AbstractFacility
{
protected override void Init()
{
Kernel.ComponentRegistered += OnComponentRegistered;
}
private void OnComponentRegistered(string key, IHandler handler)
{
var serviceProperties = handler.ComponentModel.Implementation
.GetProperties()
.Where(p => Attribute.IsDefined(p, typeof(MyComponentAttribute)))
.ToArray();
if (!serviceProperties.Any())
return;
var componentObject = ?????;
foreach (var serviceProperty in serviceProperties)
{
var interfaces = FindInterfacesRepresentedByProperty(serviceProperty.PropertyType);
var instance = serviceProperty.GetValue(componentObject, null);
Kernel.Register(Component.For(interfaces)
.Instance(instance)
.LifestyleSingleton());
}
}
}
我暂时使用这样的hack:
var componentObject = Kernel.Resolve(handler.ComponentModel.Services.First());
但是,尽管它在一般情况下工作,但只有当我在类声明中遵循一些严格的规则时,它才能正确地完成它的工作。不管怎样,这都很糟糕。
正如您所说,这种方法有些限制,看起来工厂组件必须是单例的。我认为更好的方法是在注册顶级组件的代码中处理这个问题。您可以将其封装在扩展方法中,以保持注册的流畅样式并允许重用。当你注册顶级组件时,你就可以访问实例,并且可以使用反射来访问属性。