怎么在城堡里.从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());

但是,尽管它在一般情况下工作,但只有当我在类声明中遵循一些严格的规则时,它才能正确地完成它的工作。不管怎样,这都很糟糕。

怎么在城堡里.从IHandler中获取组件对象

正如您所说,这种方法有些限制,看起来工厂组件必须是单例的。我认为更好的方法是在注册顶级组件的代码中处理这个问题。您可以将其封装在扩展方法中,以保持注册的流畅样式并允许重用。当你注册顶级组件时,你就可以访问实例,并且可以使用反射来访问属性。