Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Task<IEnumerable<DynamicNode>> instead of IEnumerable<DynamicNode> #45

Open
tugberkugurlu opened this issue Apr 29, 2012 · 8 comments
Open

Comments

@tugberkugurlu
Copy link

While we are working with DynamicNodes, we need to create a new class which derives from DynamicNodeProviderBase abstract class. Inside that class, we need to override one method as follows:

public abstract IEnumerable<DynamicNode> GetDynamicNodeCollection();

There are some cases which takes long time for that collection to load.if there is lots of data inside the database. For example, I have one currently and it takes approx. 400 ms. I am not sure but is there a way for the future releases to make this method's return type as Task<IEnumerable<DynamicNode>> so that it doesn't have to wait, returns the result immediately and builds the sitemap on the background?

I am thinking that this would also cause some problems even if this is possible. Any idea?

@maartenba
Copy link
Owner

The underlying ASP.NET SiteMap infrastructure will probably go bezerk on this. In theory, it can, but it will result in some users seeing only parts of the sitemap every now and then.

@tugberkugurlu
Copy link
Author

So, it is not something possible in practice.

I think you got what I am after. Currently, The output result is cached and this effects the first and the others hits when the cache has been invalidated. I wonder if there is anyway that your think to make this sorts of things better.

@mjhilton
Copy link

mjhilton commented Jun 8, 2012

Hi guys,

I've come across a similar issue, but have taken a different approach to solving it in my fork. The project I'm working on has a page structure something like this:

Home > Projects > Project Details > Edit Project

I wanted to replace the "Project Details" title with the name of the project, so that the breadcrumb would look like this:

Home > Projects > "My First Project" > Edit Project

So that the user could easily see which project they were working on. However, due to the number of projects in the DB and the dynamic nature of their titles, it's not feasible to use DynamicNodeProvider to load them all up at run-time.

Instead, I added a new concept, ISiteMapNodeDynamicTitleProvider, which is an extensibility point where a consumer can create a class which provides an alternative title for a given node at display-time, rather than at site-map-generation-time on initial load.

Would this functionality help with your DB load issues? And would it be of value to pull back into the main repository? I hadn't been able to find an easy way to perform this functionality with the existing codebase, but if I've missed something already built in, please let me know :)

@tugberkugurlu
Copy link
Author

@mjhilton That sounds like solution to the problem I faced. I will checked that repository out and give it a try.

@mjhilton
Copy link

mjhilton commented Jun 8, 2012

I haven't put a sample implementation in the MusicStore app yet... I'll put one up when I get a chance so you can see how I've used it :)

@tugberkugurlu
Copy link
Author

@mjhilton ah, that would be awesome. thx!

@mjhilton
Copy link

mjhilton commented Jun 8, 2012

Sorry, going away for the weekend so code will have to be in comment; don't have time to update the repo yet.

This is probably not the best implementation, in fact I think the whole set-up needs a bit more work. But basically, an instance of this class will get spun up every page load which includes the "Projects/Details" action, it uses Mvc's DependencyResolver to create an instance of the appropriate repository (you could just new one if you like/need), and pulls the title of that project only.

I don't know if I'm using the "key" attribute correctly, and haven't even thought about caching or anything like that. But you get the idea :)

SiteMapNode looks like this:

<mvcSiteMapNode title="Project Details" controller="Projects" action="Details" preservedRouteParameters="projectId" key="projectId" dynamicTitleProvider="MySolution.Web.Helpers.ProjectSiteMapNodeTitleProvider, MySolution.Web">

Implementation ProjectSiteMapNodeTitleProvider looks like this:

public string GenerateTitle(SiteMapNode node, HttpContext context, IDictionary<string, object> sourceMetadata)
{
    var mvcNode = node as MvcSiteMapNode;
    if (mvcNode == null)
        return node.Title;

    long projectId;
    if (!long.TryParse(mvcNode.RouteValues[mvcNode.Key].ToString(), out projectId))
        throw new InvalidOperationException("Expected key to be projectId");

    var projectRepo = DependencyResolver.Current.GetService<IRepository<Project>>();
    var project = projectRepo.Single(p => p.Id == projectId);

    return string.Format("{0} ({1})", project.Title, project.Id);
}

@noocyte
Copy link

noocyte commented Jan 21, 2013

This sort of functionality would be great 'out of the box'; ie delay resolving the actual path, but providing an OK default. Did you ever do anything with this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants