.Net Core中具有依賴注入的自定義路由約束

asp.net-core asp.net-core-mvc asp.net-mvc-routing dependency-injection entity-framework-core

我正在嘗試實現一個自定義路由約束,該約束將檢查數據庫以獲取信息。我已經獲得了路由約束,但是當我嘗試將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,因為我需要指定一個連接字符串,這會在我們實現的dev / production連接字符串設置中引發一個大扳手。

我的問題:

為什麼需要無參數構造函數?

為什麼我的路線會被叫兩次? (一次注入ctr,一次使用無參數ctr)

是否有更好的方法將依賴注入到IRouteConstraint的實現中?

是否有更好的方法可以做到這一點?我正在嘗試為存儲在數據庫中的頁面提供自定義URL。

任何幫助表示讚賞!謝謝!

一般承認的答案

我認為你在MapRoute中應用了兩次約束,一次在模板參數中(系統將在沒有構造函數的情況下創建約束類的實例),然後在constraints參數中。我認為您的答案是將模板更改為just

template: "{*dynamicPageFriendlyUrl}"

然後,系統將不會嘗試在模板級別應用約束。


熱門答案

在Match功能獲得數據庫服務

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


Related

許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow