views:

776

answers:

2

I noticed that the MapRoute extension includes an overload that accepts a string[] parameter which is called 'namespaces'. I read what Google had for me on it, and supposedly this is to help the framework find controllers in places it wouldn't otherwise look.

I did some spiking, and tried putting controllers in weird locations. I put one in the Scripts folder; I even built one in a separate assembly with a separate root namespace.

Without putting anyting in the namespaces param, everything worked fine. If I put just one of the namespaces in the namespaces param, it still found all my controllers. I thought maybe it would use that array to disambiguate between similarly named controllers, but that didn't happen either. A HomeController in MyProj.Controllers and one in SomeOtherName.Stuff would collide still.

So my question is, is that parameter deprecated? Or is it still used somehow in a way that I have yet to discern?

+2  A: 

No, the value is not deprecated. It is used in DefaultControllerFactory.cs. Note that if the value is supplied, it completely replaces the standard name spaces searched. When the parameter is not supplied, the name spaces searched our determined by:

HashSet<string> nsDefaults = new HashSet<string>(ControllerBuilder.DefaultNamespaces, StringComparer.OrdinalIgnoreCase);

When the parameter is supplied, the list you supply replaces this value.

In either case, DefaultControllerFactory calls:

GetControllerTypeWithinNamespaces(controllerName, nsDefaults);

...with the list, either the one you supplied, or the default. So it is clear that the value is supported.

When you look at the source code there, and in ControllerTypeCache, you can see the real purpose of the namespaces value: It does not cause the controller factory to look in places that would not otherwise look; rather it is a filter. In other words, it prevents the default controller factory from looking and name spaces that it would otherwise search for controllers.

Craig Stuntz
I recognize that that's how it's supposed to work, and I found the same spot you're describing in the DefaultControllerFactory, but when I ran the above-described tests, that's not how it worked. I supplied namespaces that didn't exist, and the factory still found my controller.
Paul
The code in ControllerTypeCache sure looks like it works that way to me. You can debug through it by building with the source. Perhaps there is something you have not supplied?
Craig Stuntz
I agree that it looks that way, and I built w/ the source when testing before; I'll try again w/ some different params.
Paul
+3  A: 

Ok, so after further testing, I figured out that it is not a filter, exactly, but it kinda is also. I gave you 'answer' credit even though you're partially wrong.

So, it does, after all, act like I thought it should which is to say it disambiguates. Basically, the logical flow is something like this:

  • Look for a namespace in the _cache that matches one in the namespaces array
    • if that's found, look for a controller of the right name
    • -- if that's found, return it
    • -- if it's not found, return search everywhere else that it'd normally look
  • if it's not found, search everywhere lese

So, in short, my thought that the namespaces array would serve to disambiguate was correct. The reason my first test in that regard failed is that it only does a perfect match, and I made the mistake of using just the root n/s from the assembly (in other wordss, MyRoot instead of MyRoot.Controllers).

What this namespaces thing allows, then, is to have a HomeController in two different namespaces and match them differently depending on the url or params.

Paul