Overriding the default NavigationManager

Topics: Troubleshooting, Writing modules
Developer
Feb 21, 2011 at 10:14 PM

Hi!

I'm currently developing the functionality to add custom menus and I'm stuck on injecting this feature into the navigation building pipeline:/

The NavigationManager class assumes that there exists a separate, hardcoded INavigationProvider for all the menus it builds:

private IEnumerable<IEnumerable<MenuItem>> GetSources(string menuName) {
            foreach (var provider in _providers) {
                if (provider.MenuName == menuName) {
                    var builder = new NavigationBuilder();
                    provider.GetNavigation(builder);
                    yield return builder.Build();
                }
            }
        }

It just checks every provider for match on a MenuName property.

I'd like to allow users to create menus via UI, which I already did, but don't have a clue how to make them "buildable" via NavigationManager without altering the core code or a dirty workaround (which I'll explain below). For obvious reasons I have a single implementation of INavigationProvider, which fetches the appropriate data from the db, depending on the menu name (and here the problem starts).

  • First approach: Dynamically add the Autofac registrations for every menu defined by user. Bump! I cannot inject dependencies to my Autofac.Module implementation, so I don't have access to db at the time of container creation...
  • Second approach: As I cannot override the string class and the == operator to force MenuName be equal to everything besides "admin" and "menu" (so it gets used every time the custom menu is to be rendered), I don't have the possibility to know which menu my provider has to return. Bump!:/
  • Third approach and the dirty workaround in one: Override the NavigationManager and change the provider selecting logic shown in the code above. Bump! It's private so I would have to copy&paste the whole code (as other helper methods are private too...). Ok, it's doable but dirty:/
  • Fourth approach and another dirty workaround in one:  Override the NavigationManager class, alter the injected collection of INavigationProviders adding a newly created provider for every defined custom menu and inject this collection to the base constructor. It'll work, but directly creating objects which should be inserted via IoC container doesn't look well:/

Maybe there is some better approach there I'm not aware of to solve this problem? If not, I'll stick probably to the last solution.

- Piotr

Coordinator
Feb 21, 2011 at 10:40 PM

Could you capture that in an issue so that it's easier to track and so we can see if we can provide a better workaround or solution?

Developer
Feb 21, 2011 at 11:26 PM

Sure, I'll post an issue, thanks!