【问题标题】:Custom Route Constraint with Dependency Injection in .Net Core.Net Core 中具有依赖注入的自定义路由约束
【发布时间】:2017-10-19 18:43:30
【问题描述】:

我正在尝试实现一个自定义路由约束来检查数据库中的信息。我已经使路由约束起作用,但是在尝试将 DbContext 注入类以使用数据库时遇到了无参数构造函数问题。这是我的代码:

我的自定义路线约束:

    public class DynamicPageRouteConstraint : IRouteConstraint
    {
        public const string ROUTE_LABEL = "dbDynamicRoute";
        private ApplicationDbContext db;

        public DynamicPageRouteConstraint(ApplicationDbContext _db)
        {
            db = _db;
        }

        public bool Match(HttpContext httpContext, IRouter route, string routeKey, RouteValueDictionary values, RouteDirection routeDirection)
        {
            List<string> items = db.DynamicPages.Select(p => p.Url).ToList();

            if (items.Contains(values["dynamicPageFriendlyURL"]))
            {
                return true;
            }

            return false;
        }
    }

Startup.cs:

    public void ConfigureServices(IServiceCollection services)
    {
        ...
        services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(ConnectionString));

        services.Configure<RouteOptions>(options =>
        {
            options.ConstraintMap.Add(DynamicPageRouteConstraint.ROUTE_LABEL, typeof(DynamicPageRouteConstraint));
        });

        services.AddMvc();
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        ...

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "DynamicPageRoutes",
                template: "{*dynamicPageFriendlyURL:" + DynamicPageRouteConstraint.ROUTE_LABEL + "}",
                defaults: new { controller = "DynamicPage", action = "Loader" },
                constraints: new { dynamicPageFriendlyURL = new DynamicPageRouteConstraint(app.ApplicationServices.GetRequiredService<ApplicationDbContext>()) });

            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });
    }

我的问题是这样的:

当它遇到我在 startup.cs 中的路由时,它会立即抱怨缺少无参数构造函数。

如果我在我的 RouteConstraint 实现中放置一个无参数构造函数,我可以让代码正常工作,但是在访问路由时,它会被命中两次,一次是注入我的依赖项,然后再次使用无参数构造函数,这意味着没有 db对象实例化。

我不想通过实例化一个新的 dbcontext 对象来放弃注入 dbContext,因为我需要指定一个连接字符串,这会在我们已经实现的开发/生产连接字符串设置中造成很大的麻烦。

我的问题:

为什么需要无参数构造函数?

为什么我的路由会被调用两次? (一次注入 ctr,一次使用无参数 ctr)

有没有更好的方法将依赖注入到 IRouteConstraint 的实现中?

有没有更好的方法来做到这一点?我正在尝试为存储在数据库中的页面提供自定义 URL。

感谢任何帮助!谢谢!

【问题讨论】:

    标签: dependency-injection asp.net-core asp.net-core-mvc asp.net-mvc-routing entity-framework-core


    【解决方案1】:

    在 Match 函数中获取数据库服务

    var db = (ApplicationDbContext)httpContext.RequestServices.GetService(typeof(ApplicationDbContext));
    

    【讨论】:

      【解决方案2】:

      我认为您在 MapRoute 中应用了两次约束,一次在模板参数中(系统将在其中创建没有构造函数的约束类的实例),然后在约束参数中。我认为您的答案是将您的模板更改为只是

      template: "{*dynamicPageFriendlyUrl}"
      

      然后系统不会尝试在模板级别应用约束。

      【讨论】:

      • 谢谢!这解决了双重调用和依赖注入/构造函数的问题。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-01-09
      • 2018-11-16
      • 2016-07-03
      • 2020-09-20
      • 2016-05-22
      • 1970-01-01
      • 2021-07-15
      相关资源
      最近更新 更多