首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >基于数据库上下文和模型创建实例的路由工厂

基于数据库上下文和模型创建实例的路由工厂
EN

Code Review用户
提问于 2015-04-02 18:34:31
回答 1查看 172关注 0票数 6

我试图弥合数据库上下文和存储在数据库中的路由之间的差距。

工厂的设计使得当在其他程序集中使用时,您必须使用已知包含DbSet的数据库上下文,该上下文可以提供所需的数据来填充路由。

在工厂所在的程序集中,可以指定要使用的数据库上下文,以便如果创建了更多的路由类型,则路由工厂可以向程序集中的其他类提供不同类型的路由。

但是,最初工厂背后的想法是,与工厂引用程序集的程序集也可以指定数据库上下文或模型,只要它继承了基本数据库上下文或模型。我知道使方法内部化可以防止这一点,但是方法是内部的,因为如果我重构所有方法的工作方式,它们可能会被删除。

以下是全班学生:

代码语言:javascript
复制
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
    }
}

正如您可以看到的那样,类大量使用反射,这不利于性能,但是,这个工厂的预期用途是,它只需要获得一个路由,即所有路由。

我的问题是:

  • 根据刚才所说的,我应该把内部的方法保留下来,还是公开呢?
  • 工厂是否应该进行重构以提高性能,尽管其意图是每一次请求只使用它一次?
EN

回答 1

Code Review用户

回答已采纳

发布于 2015-09-11 14:09:09

您在名称空间本身中有所有这些using语句的特殊原因吗?

这一行:

DbContextTypeWrapper,SiteTree> dbContextTypeWrapper = new DbContextTypeWrapper,SiteTree>();

为我扔了一面灰色的旗子。也许您应该考虑将DbContextTypeWrapper注入RouteFactory?它似乎对某些细节有着可怕的依赖,这些细节是可以抽象的。

另一个建议是考虑泛型,考虑到您也依赖于SiteTree

理想的解决方案将是您所依赖的接口ISiteTree,而不管SiteTree实现如何。您可以提供默认的SiteTree实现,或者允许其他程序集提供自己的程序集。

类似地,internal的使用倾向于向某些特定属性提供帮助,例如,程序集之间的行为可能有所不同。这特别下流。您应该考虑标记internal方法public,或者标记它们private

根据您的访问权限,您应该再次考虑接口/泛型,以便允许DbContextTypeWrapper在程序集之间略有变化。通过将public实现限制为SapphireDbContext,还可以将其限制为SapphireDbContext支持的那些DB类型。(如果它只支持MSSQL,那么您将需要一个MSSQL服务器来处理您在其中使用的每个其他项目。)

虽然我一般不提倡使用var,但是您可以用它缩短一些行。(尤其是那些长得令人发指的。)

票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/85712

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档