.Net Core 中具有依赖注入的自定义路由约束
Custom Route Constraint with Dependency Injection in .Net Core
我正在尝试实现一个自定义路由约束,该约束将检查数据库中的信息。我已经使路由约束起作用,但是在尝试将 DbContext 注入 class 以使用数据库时,我 运行 遇到了无参数构造函数问题。这是我的代码:
我的自定义路由约束:
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 实现中放置一个无参数构造函数,我可以让代码工作,但是当到达路由时,它会被命中两次,一次是注入我的依赖项,然后再次使用无参数构造函数,这意味着没有实例化数据库对象。
我不想通过实例化一个新的 dbcontext 对象来放弃注入 dbContext,因为我需要指定一个连接字符串,这会在我们已经实现的 dev/production 连接字符串设置中抛出一个大问题.
我的问题:
为什么需要无参数构造函数?
为什么我的路线会被调用两次? (一次是注入点击率,一次是无参数点击率)
是否有更好的方法将依赖注入到 IRouteConstraint 的实现中?
有没有更好的方法来做到这一点?我正在尝试为存储在数据库中的页面提供自定义 URL。
感谢任何帮助!谢谢!
我认为您在 MapRoute 中应用了两次约束,一次是在模板参数中(系统将在其中创建一个没有构造函数的约束实例 class),然后是在约束参数中。我认为您的答案是将模板更改为
template: "{*dynamicPageFriendlyUrl}"
然后系统将不会尝试在模板级别应用约束。
在匹配函数中获取数据库服务
var db = (ApplicationDbContext)httpContext.RequestServices.GetService(typeof(ApplicationDbContext));
我正在尝试实现一个自定义路由约束,该约束将检查数据库中的信息。我已经使路由约束起作用,但是在尝试将 DbContext 注入 class 以使用数据库时,我 运行 遇到了无参数构造函数问题。这是我的代码:
我的自定义路由约束:
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 实现中放置一个无参数构造函数,我可以让代码工作,但是当到达路由时,它会被命中两次,一次是注入我的依赖项,然后再次使用无参数构造函数,这意味着没有实例化数据库对象。
我不想通过实例化一个新的 dbcontext 对象来放弃注入 dbContext,因为我需要指定一个连接字符串,这会在我们已经实现的 dev/production 连接字符串设置中抛出一个大问题.
我的问题:
为什么需要无参数构造函数?
为什么我的路线会被调用两次? (一次是注入点击率,一次是无参数点击率)
是否有更好的方法将依赖注入到 IRouteConstraint 的实现中?
有没有更好的方法来做到这一点?我正在尝试为存储在数据库中的页面提供自定义 URL。
感谢任何帮助!谢谢!
我认为您在 MapRoute 中应用了两次约束,一次是在模板参数中(系统将在其中创建一个没有构造函数的约束实例 class),然后是在约束参数中。我认为您的答案是将模板更改为
template: "{*dynamicPageFriendlyUrl}"
然后系统将不会尝试在模板级别应用约束。
在匹配函数中获取数据库服务
var db = (ApplicationDbContext)httpContext.RequestServices.GetService(typeof(ApplicationDbContext));