如何在Castle Windsor中使用特定界面注册多个服务

时间:2012-01-11 15:50:35

标签: castle-windsor

我有以下注册:

container.Register(AllTypes.FromAssemblyContaining<ITabViewModel>().BasedOn<ITabViewModel>());

两个班级:

public class StructureDecorationViewModel : NotificationObject, ITabViewModel
{
...
}

public abstract class NotificationObject : INotifyPropertyChanged
{
...
}

两个解析器:

serviceProvider.ResolveAll<System.ComponentModel.INotifyPropertyChanged>()
serviceProvider.ResolveAll<ITabViewModel>()

这两个解析器都提供了StructureDecorationViewModel,如何过滤注册以便我只注册ITabViewModel而不是INotifyPropertyChange?

1 个答案:

答案 0 :(得分:4)

要只注册一个接口,通常使用FirstInterface:

AllTypes
    .FromAssemblyContaining<ITabViewModel>()
    .BasedOn<ITabViewModel>()
    .WithService
    .FirstInterface();

但是在这种情况下,你最终会得到针对INotifyPropertyChanged注册的服务,这不是你想要的,因为它从基类中选择第一个接口(看看ServiceDescriptor类,看看有哪些其他注册可用)。

您需要的是Select方法,它允许您定义要注册服务的类型:

AllTypes
    .FromAssemblyContaining<ITabViewModel>()
    .BasedOn<ITabViewModel>()
    .WithService
    .Select(typeof(ITabViewModel));

但是,如果你想保持更通用的东西,有人编写了一个扩展方法来查看正在注册的服务,并选择派生类的第一个接口(http://www.hightech.ir/SeeSharp/windsor-注册服务接口):

public static BasedOnDescriptor FirstInterfaceOnClass(this ServiceDescriptor serviceDescriptor)
{
   return serviceDescriptor.Select((t, bt) =>
   {
       var baseInterfaces = t.BaseType.GetInterfaces();
       var interfaces = t.GetInterfaces().Except(baseInterfaces);

       return interfaces.Count() != 0 ? new[] {interfaces.First()} : null;
   });
}

允许您这样做:

AllTypes
    .FromAssemblyContaining<ITabViewModel>()
    .BasedOn<ITabViewModel>()
    .WithService
    .FirstInterfaceOnClass();