1
\$\begingroup\$

I have this simple class where I load an object from the database and store it into the RouteContext.DataTokens because I need to access it through out the request.

In this example the RouteContext is injected via the constructor but I'm not sure that's the right thing to do here, maybe the RouteContextshould be a method parameter instead?

public class RouteResolverTrie : IRouteResolverTrie
{
    private readonly IDocumentStore documentStore;
    private RouteContext context;

    public RouteResolverTrie(RouteContext context, IDocumentStore documentStore)
    {
        this.documentStore = documentStore;
        this.context = context;
    }

    public Trie LoadTrie()
    {
        if(context.DataTokens.ContainsKey("some key")) {
            return context.DataTokens["trie"] as Trie;
        }
        else {
            using(var session = documentStore.OpenSession()) {
                var trie = session.Load<Trie>("trie/1");
                context.DataTokens["trie"] = trie;
                return trie;
            }
        }
    }
}

This is how the routing works in vNext and this is my first entry point. As you can see I use LoadTrie() in the method RouteAsync which in turn uses the RouteContext to store temporary data through out the request. So, the question is, should I instantiate the DefaultRouter with a new RouteResolverTrie that takes the current RouteContext as a constructor parameter or should it be a method parameter?

public class DefaultRoute : IRouter
{
    private readonly IRouter _target;
    private IRouteResolverTrie _routeResolverTrie;

    public DefaultRoute(IRouter target, IRouteResolverTrie routeResolverTrie) {
        _target = target;
        _routeResolverTrie = routeResolverTrie;
    }

    public string GetVirtualPath(VirtualPathContext context)
    {
        return null;
    }

    public async Task RouteAsync(RouteContext context)
    {
        var trie = _routeResolverTrie.LoadTrie();
    }
}
\$\endgroup\$
0

1 Answer 1

1
\$\begingroup\$

Since you need something that persists for the duration of request, a better place would be to add to RequestContext. So there are couple of ways to handle this more cleanly:

Add a base controller and add additional data to RequestContext:

protected override void Execute(System.Web.Routing.RequestContext requestContext)
{
    // get additional data
    ...

    // add them to routeDate
    requestContext.RouteData.Values.Add(key, value);
    ...

    base.Execute(requestContext);
}

Add your own custom RouteHandler and add additional data to RequestContext:

public class CustomRouteHandler : MvcRouteHandler 
{ 

    protected override IHttpHandler GetHttpHandler(RequestContext requestContext){
           // add to HttpContext
           requestContext.HttpContext.Items["Custom"] = data;

           // or RouteData
           requestContext.RouteData.Values.Add(key, value);
        }
        return base.GetHttpHandler(requestContext);
    }

}

// define route with custom handler 
Route customRoute = new Route (
    url: ...,
    defaults: null,
    constraints: ...,
    routeHandler: new CustomRouteHandler()
});

routes.Add(customRoute);
\$\endgroup\$
4
  • \$\begingroup\$ I forgot to mention that I'm using ASP.NET vNext but I guess I can replace the RouteHandler. I don't know if I like the idea of loading additional stuff in the RouteHandler, in my example the RouteResolverTrie has a well defined responsibility, to load and "cache" the Trie, but if I move this to a CustomRouteHandler it wouldn't be as clear or what do you think? \$\endgroup\$
    – marcus
    Commented Sep 4, 2014 at 16:13
  • \$\begingroup\$ If you think about it, RouteResolverTrie is your custom RouteHandler. Only thing is that now it'll be modifying something it is supposed to! \$\endgroup\$
    – Mrchief
    Commented Sep 4, 2014 at 16:19
  • \$\begingroup\$ In other words, that's what CustomRouteHandlers are meant to do - it makes it explicit and cleaner because you know exactly who's modifying the route. \$\endgroup\$
    – Mrchief
    Commented Sep 4, 2014 at 16:22
  • \$\begingroup\$ I see, in MVC 6/vNext there are no split between the router and the http handler. I have updated my question with a simple IRouter implementation and I hope you understand what I try to do. \$\endgroup\$
    – marcus
    Commented Sep 5, 2014 at 6:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.