I am trying to bridge the gap between the database context and routes that are stored in the database.
The factory is designed so that when used in other assemblies, you are forced to use the database context which is known to contain the DbSet which can provide the required data to populate the route.
In the assembly in which the factory resides, you can specify the database context to use so that if more route types are created the route factory can provide different types of route to other classes within the assembly.
However, the idea initially behind the factory was that the assemblies which reference the assembly with the factory could also specify a database context or model as long as it inherits the base database context or model. I'm aware that making the methods internal prevents this, but the methods have been made internal as they may be removed if I refactor the way everything works.
The following is the class:
namespace Sapphire.Cms.Web.Routing
{
using Sapphire.Cms.Data.Entity;
using Sapphire.Cms.Models;
using System;
using System.Web.Routing;
public class RouteFactory : IRouteProvider
{
public virtual RouteBase GetRoute(IRouteHandler routeHandler)
{
DbContextTypeWrapper<SapphireDbContext<SiteTree>, SiteTree> dbContextTypeWrapper = new DbContextTypeWrapper<SapphireDbContext<SiteTree>, SiteTree>();
return GetRoute(dbContextTypeWrapper, routeHandler);
}
internal virtual RouteBase GetRoute(DbContextTypeProvider databaseContextTypeProvider, IRouteHandler routeHandler)
{
return GetRoute(databaseContextTypeProvider, typeof(SiteTree), routeHandler);
}
internal virtual RouteBase GetRoute(DbContextTypeProvider databaseContextTypeProvider, Type model, IRouteHandler routeHandler)
{
Type catchallRoute = typeof(CatchallRoute<,>).MakeGenericType(new Type[] {
databaseContextTypeProvider.DbContextType,
model
});
Type routeTypeWrapper = typeof(RouteTypeWrapper<>).MakeGenericType(new Type[] {
catchallRoute
});
RouteTypeProvider routeTypeProvider = (RouteTypeProvider)Activator.CreateInstance(routeTypeWrapper);
return GetRoute(routeTypeProvider, routeHandler);
}
private static RouteBase GetRoute(RouteTypeProvider routeTypeProvider, IRouteHandler routeHandler)
{
Object[] constructorParameters = new Object[]
{
routeHandler
};
return (RouteBase)Activator.CreateInstance(routeTypeProvider.RouteType, constructorParameters);
}
#region IRouteProvider Members
RouteBase IRouteProvider.GetRoute(IRouteHandler routeHandler)
{
return GetRoute(routeHandler);
}
#endregion
}
}
As you can see the class makes heavy use of reflection, which is bad for performance, however the intended use of this factory is that it should only ever have to get one route, a catchall route.
My questions are:
- Based on what was said, should I keep the internal methods internal or make them public?
- Should the factory be refactored to improve performance despite the intention being to only ever use it once per request?