Pregunta

I'm trying to build a plugin architecture for asp.net MVC which would allow Controllers to be overriden.

On my App_Start() I have this:

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

And a bit before an installer for all Controllers inside the Assembly:

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

This is based on the Windsor Tutorial.

Now, on my plugin or module, I would like to register new Controllers and be able to override specific controllers already registered on the base MVC application.

The problem is, there isn't a way to call .Overridable() or .IsDefault() when using the registration method above. How could I do something like this:

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

In essence, how to override something registered by type?

¿Fue útil?

Solución

When you are using a convention registration like Classes, you cannot call unitary methods like SetDefault directly; that wouldn't make sense since you're returning a collection of elements, all of which cannot be the default one. (To be more precise, the convention lets you declare descriptions of the components that interest you; the type used is a BasedOnDescriptor. The IsDefault method exists on the ComponentRegistration class)

However it is possible to call a Configure method (and its variations ConfigureIf and ConfigureFor) that lets you call unitary methods on a component. So you could call the IsDefault using the Configure method

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

Of course you would need to define how the default component is determined. For example if the default component name contains the word "default" you may use the ConfigureIf method:

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

Otros consejos

In Windsor, the first registration wins, so subsequent registrations of a service won't override the initial registration.

So what you will want to do is perform your most specific registrations first, then do the more general, convention-based auto-registrations.

See section "In Windsor first one wins" on this page.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top