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

.NET 6带依赖注入与工厂传参的工厂类实现报错排查

问题分析与解决方案

错误根源

报错的核心原因是错误的服务注册:你直接将Novel和ShortNovel注册为IBook的实现(services.AddTransient<IBook, Novel>()),而这两个类的构造函数需要title和author这两个无法由DI容器自动解析的字符串参数。DI容器在启动时会验证服务描述符,尝试创建Novel实例时找不到对应的string服务,因此抛出异常。

同时,你注册的两个Func<IBook>服务不仅多余,还会覆盖彼此(最后注册的ShortNovel版本会生效),且同样会触发DI容器尝试创建实例,导致相同错误。

修复步骤

1. 清理错误的服务注册

移除以下无效的注册代码:

services.AddTransient<IBook, Novel>();
services.AddTransient<IBook, ShortNovel>();
services.AddTransient<Func<IBook>>(x => () => x.GetService<Novel>()!);
services.AddTransient<Func<IBook>>(x => () => x.GetService<ShortNovel>()!);

2. 注册工厂类

将你的IBookFactory和BookFactory注册到DI容器:

services.AddTransient<IBookFactory, BookFactory>();

3. 确保依赖项已注册

确认IFileSystem、IShelf以及日志服务(ILogger<T>)已正确注册到DI容器,例如:

// 示例:注册自定义依赖
services.AddTransient<IFileSystem, FileSystemImplementation>();
services.AddTransient<IShelf, ShelfImplementation>();
// .NET 6默认已注册日志服务,无需额外添加

4. 验证工厂使用方式

在需要创建IBook实例的地方,注入IBookFactory并调用Create方法:

public class BookService
{
    private readonly IBookFactory _bookFactory;

    public BookService(IBookFactory bookFactory)
    {
        _bookFactory = bookFactory;
    }

    public void CreateAndUseBook()
    {
        var novel = _bookFactory.Create("Novel", "The Great Gatsby", "F. Scott Fitzgerald");
        var shortNovel = _bookFactory.Create("ShortNovel", "The Lottery", "Shirley Jackson");
        // 使用实例...
    }
}

原理说明

ActivatorUtilities.CreateInstance<T>的工作机制是:

  1. 查找目标类型(如Novel)的构造函数,优先选择参数数量最多的构造函数
  2. 从DI容器中自动解析所有可识别的服务类型参数(如ILogger<Novel>、IFileSystem、IShelf)
  3. 使用你传递的自定义参数(title、author)填充剩余的参数位置

因此,无需将Novel/ShortNovel直接注册为IBook的实现,工厂会通过ActivatorUtilities完成实例的创建,同时兼顾DI依赖注入和自定义参数传递。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 17:53:28