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

依赖注入含必填参数时的通用面包屑助手类重构咨询

Feasibility & Optimization Advice for Your CoreFactoryHelper Refactoring

Absolutely, this refactoring plan is not only feasible—it’s a perfect application of the DRY (Don’t Repeat Yourself) principle that will cut down on redundant code and make your codebase much easier to maintain. Let’s walk through how to implement it properly, plus key optimizations to fix subtle issues in your original code.

Step 1: Implement the Generic CoreFactoryHelper

Since your helper classes only differ by two values (_controller name and the root breadcrumb text), we can extract those as constructor parameters and build a reusable core class. Here’s the refactored code:

public interface IBreadcrumbFactoryHelper
{
    BreadcrumbModel GetBreadcrumb(string name, string action, object routeValues);
}

public class CoreFactoryHelper : IBreadcrumbFactoryHelper
{
    private readonly string _controllerName;
    private readonly string _rootBreadcrumbLabel;
    private readonly UrlHelper _urlHelper;

    // Inject dependencies + configuration values directly in the constructor
    public CoreFactoryHelper(UrlHelper urlHelper, string controllerName, string rootBreadcrumbLabel)
    {
        _urlHelper = urlHelper ?? throw new ArgumentNullException(nameof(urlHelper));
        _controllerName = controllerName ?? throw new ArgumentNullException(nameof(controllerName));
        _rootBreadcrumbLabel = rootBreadcrumbLabel ?? throw new ArgumentNullException(nameof(rootBreadcrumbLabel));
    }

    public BreadcrumbModel GetBreadcrumb(string name, string action, object routeValues)
    {
        var breadcrumb = new BreadcrumbModel();
        
        // Use the injected UrlHelper instead of pulling from DependencyResolver
        var rootUrl = _urlHelper.Action("Index", _controllerName).ToLower();
        breadcrumb.AddItem(_rootBreadcrumbLabel, rootUrl);

        // Fix the duplicate condition check from your original code
        if (!string.IsNullOrWhiteSpace(action) && !string.IsNullOrWhiteSpace(name))
        {
            string itemUrl = routeValues == null 
                ? _urlHelper.Action(action, _controllerName) 
                : _urlHelper.Action(action, _controllerName, routeValues);
            
            breadcrumb.AddItem(name, itemUrl?.ToLower());
        }

        return breadcrumb;
    }
}

Key Optimizations & Improvements

1. Ditch DependencyResolver.Current

Your original code pulls a second UrlHelper from the dependency resolver even though it’s already injected—this is unnecessary and breaks proper dependency injection practices. Using the injected instance makes your code easier to test (you can mock UrlHelper for unit tests) and aligns with inversion of control principles.

2. Add Parameter Validation

We’ve added null checks in the constructor to catch invalid configurations early, preventing null reference exceptions later in runtime.

3. Fix the Duplicate Condition

Your original code had a typo: !string.IsNullOrWhiteSpace(action) && !string.IsNullOrWhiteSpace(action)—we corrected this to check both action and name, which is what you intended.

4. Register Specific Instances in Your DI Container

To use this generic helper for different controllers, register dedicated instances in your dependency injection setup. For example, in ASP.NET Core:

// Register for VideoLibrary
services.AddScoped<IBreadcrumbFactoryHelper>(sp => 
    new CoreFactoryHelper(
        sp.GetRequiredService<UrlHelper>(),
        "VideoLibrary",
        "Video Library"
    )
);

// If you need multiple distinct helpers (e.g., for a MusicLibrary), add another registration:
services.AddScoped<IBreadcrumbFactoryHelper>(sp => 
    new CoreFactoryHelper(
        sp.GetRequiredService<UrlHelper>(),
        "MusicLibrary",
        "Music Library"
    )
);

// Alternatively, use named registrations or a marker interface if you need to resolve specific helpers

Why This Works

By extracting the variable parts as constructor parameters, you eliminate all duplicate logic while keeping the flexibility to support any controller’s breadcrumb needs. This approach is scalable—adding a new helper for a BookLibrary is just a new DI registration, no new class required.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 03:59:01