You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core 2自定义IRouter依赖注入与路由实现咨询

Hey there! Let's break down how to get your custom IRouteCustom set up with dependency injection and complete the implementation in ASP.NET Core 2.x.

1. Dependency Injection Configuration

First, we need to register your custom router and its dependencies in Startup.cs. Here's how to do it:

Step 1: Register Services in ConfigureServices

public void ConfigureServices(IServiceCollection services)
{
    // Register your IUnitOfWork implementation (adjust to match your actual class)
    services.AddScoped<IUnitOfWork, YourUnitOfWorkImpl>();

    // Register your custom RouteCustom, injecting the default MVC route handler, memory cache, and unit of work
    services.AddSingleton<IRouteCustom>(provider => 
        new RouteCustom(
            provider.GetRequiredService<MvcRouteHandler>(),
            provider.GetRequiredService<IMemoryCache>(),
            provider.GetRequiredService<IUnitOfWork>()
        )
    );

    // Standard MVC setup
    services.AddMvc();
}

Step 2: Replace Default Route in Configure

Next, swap out the default routing system with your custom router in the MVC pipeline:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    // Add your standard middleware (like error pages, static files) here first

    app.UseMvc(routes =>
    {
        // Clear any default routes if needed, then add your custom router
        routes.Routes.Clear();
        routes.Routes.Add(app.ApplicationServices.GetRequiredService<IRouteCustom>());
    });
}
2. Completing the RouteCustom Implementation

Now let's fill in the missing parts of your RouteCustom class, focusing on the core IRouter methods you need to implement:

public class RouteCustom : IRouteCustom
{
    private readonly IRouter _innerRouter;
    private readonly IMemoryCache _memoryCache;
    private readonly IUnitOfWork _unitOfWork;
    private const string _routeCacheKeyPrefix = "CustomRoute_";

    public RouteCustom(IRouter innerRouter, IMemoryCache memoryCache, IUnitOfWork unitOfWork)
    {
        _innerRouter = innerRouter ?? throw new ArgumentNullException(nameof(innerRouter));
        _memoryCache = memoryCache ?? throw new ArgumentNullException(nameof(memoryCache));
        _unitOfWork = unitOfWork ?? throw new ArgumentNullException(nameof(unitOfWork));
    }

    public async Task RouteAsync(RouteContext context)
    {
        var requestPath = context.HttpContext.Request.Path.Value.TrimStart('/');

        // Check cache first for performance
        if (!_memoryCache.TryGetValue(_routeCacheKeyPrefix + requestPath, out RouteMapping routeMapping))
        {
            // Fetch the route mapping from your database via UnitOfWork
            routeMapping = await _unitOfWork.RouteMappings.GetByRequestPathAsync(requestPath);
            
            if (routeMapping != null)
            {
                // Cache the result to avoid repeated database hits (adjust expiry as needed)
                _memoryCache.Set(_routeCacheKeyPrefix + requestPath, routeMapping, TimeSpan.FromHours(1));
            }
        }

        // If we found a valid mapping, update the route data to point to the target controller/action
        if (routeMapping != null)
        {
            context.RouteData.Values["controller"] = routeMapping.TargetControllerName;
            context.RouteData.Values["action"] = routeMapping.TargetActionName;

            // Add any additional route parameters here if your mappings include them
            // context.RouteData.Values["id"] = routeMapping.TargetId;
        }

        // Pass control to the inner router (the default MVC handler) to process the updated route data
        await _innerRouter.RouteAsync(context);
    }

    public VirtualPathData GetVirtualPath(VirtualPathContext context)
    {
        // This method handles reverse routing (e.g., generating URLs with Url.Action)
        // If you need to map controller/action back to a custom path, implement that logic here
        // For now, we'll delegate to the inner router to maintain default behavior
        return _innerRouter.GetVirtualPath(context);
    }
}

// Example RouteMapping entity that matches your database schema
public class RouteMapping
{
    public string RequestPath { get; set; }
    public string TargetControllerName { get; set; }
    public string TargetActionName { get; set; }
    // Add other properties as needed (e.g., route parameters, tenant IDs)
}
3. Important Things to Keep in Mind
  • Cache Invalidation: When you update route mappings in the database, make sure to clear the corresponding cache entry to avoid serving stale data. For example, after updating a RouteMapping, call _memoryCache.Remove(_routeCacheKeyPrefix + updatedMapping.RequestPath).
  • Fallback Behavior: If no matching route is found in the database, the inner router will fall back to standard MVC routing rules, so your existing controllers/actions will still work as expected.
  • Error Handling: Wrap your database calls in try/catch blocks to handle potential connection issues gracefully, preventing routing failures from crashing the app.
  • Route Order: Ensure your custom router is added to the routes.Routes collection before any other routes if you want it to take priority. If you need to mix custom and standard routes, adjust the order accordingly.

内容的提问来源于stack exchange,提问作者John Mathison

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:55:37