在Castle Windsor中,如何覆盖使用FromThisAssembly()注册的类型

时间:2014-03-20 13:01:07

标签: c# asp.net .net asp.net-mvc castle-windsor

我正在尝试为asp.net MVC构建一个插件架构,它允许覆盖控制器。

在我的App_Start()上我有这个:

ControllerBuilder.Current.SetControllerFactory(
   new WindsorControllerFactory(container));

在大会内所有控制器的安装程序之前:

public class ControllersInstaller : IWindsorInstaller
{
    public void Install(IWindsorContainer container, IConfigurationStore store) {
        container.Register(Classes.FromThisAssembly().BasedOn<IController>().LifestyleTransient());
    }
}

这基于Windsor Tutorial

现在,在我的插件或模块上,我想注册新的控制器,并能够覆盖已在基础MVC应用程序上注册的特定控制器。

问题是,在使用上面的注册方法时,没有办法调用.Overridable()或.IsDefault()。我怎么能这样做:

public void Install(IWindsorContainer container, IConfigurationStore store) {
            container.Register(Classes.FromThisAssembly().
            BasedOn<IController>().
            LifestyleTransient().
            IsDefault()); // This does not compile.

本质上,如何覆盖按类型注册的内容?

2 个答案:

答案 0 :(得分:3)

当您使用Classes之类的会议注册时,您无法直接调用SetDefault之类的单一方法;因为你要返回一个元素集合,所有这些都不是默认元素,这是没有意义的。 (更准确地说,约定允许您声明您感兴趣的组件的描述;使用的类型是BasedOnDescriptorIsDefault类上存在ComponentRegistration方法

但是,可以调用Configure方法(及其变体ConfigureIfConfigureFor)来调用组件上的单一方法。因此,您可以使用IsDefault方法

来调用Configure
var regs = Classes
           .FromThisAssembly()
           .Pick()
           .WithServiceAllInterfaces(); // dummy registration
regs.Configure(c => c.IsDefault());

当然,您需要定义默认组件的确定方式。例如,如果默认组件名称包含单词"default",您可以使用ConfigureIf方法:

regs.ConfigureIf(component => component.Name.ToLower().Contains("default"), 
                          component => component.IsDefault());

答案 1 :(得分:0)

在温莎,第一次注册获胜,因此服务的后续注册不会覆盖初始注册。

所以你要做的是先执行最具体的注册,然后执行更一般的,基于约定的自动注册。

参见&#34; 在温莎首先获胜&#34;在this页上。