具有多个接口作为构造函数中的参数的依赖注入

Posted

技术标签:

【中文标题】具有多个接口作为构造函数中的参数的依赖注入【英文标题】:Dependency Injection with multiple interfaces as parameters in constructor 【发布时间】:2021-11-02 16:15:14 【问题描述】:

我是 Core/Azure Functions 的新手,正在尝试使用 DI 容器添加依赖项。

我想将类/接口依赖添加到 DI Container:

s.AddSingleton<ITicketService>(new TicketService());
s.AddSingleton<IFoodService>(new FoodService());
s.AddSingleton<IFinancialsService>(new FinancialsService());

对于以上三个类/接口,我该如何处理它们依赖于存储库类。

s.AddSingleton<ITicketService>(new TicketService(ITicketRepository));
s.AddSingleton<IFoodService>(new FoodService(IFoodRepository));
s.AddSingleton<IFinancialsService>(
    new FinancialsService(ITicketRepository,IFoodRepository));

以下是这些类和接口的相关代码:

public interface ITicketService  ... 
public interface IFoodService  ... 
public interface IFinancialsService  ... 

public class TicketService : ITicketService

    private readonly ITicketRepository _ticketRepo;

    public TicketService(ITicketRepository ticketRepo) => _ticketRepo = ticketRepo;


public class FoodService : IFoodService 

    private readonly IFoodRepository _foodRepo;

    public FoodService(IFoodRepository foodRepo) => _foodRepo = foodRepo;


public class FinancialsService : IFinancialsService

    private readonly ITicketRepository _ticketRepo;
    private readonly IFoodRepository _foodRepo;

    public FinancialsService(ITicketRepository ticketRepo, IFoodRepository foodRepo)
    
        _ticketRepo = ticketRepo;
        _foodRepo = foodRepo;
    

    public FinancialStats GetStats() ...

任何工作示例都将受到赞赏。

【问题讨论】:

【参考方案1】:

在注册类型时使用重载,实现也被声明。

s.AddSingleton<ITicketService, TicketService>();
s.AddSingleton<IFoodService, FoodService>();
s.AddSingleton<IFinancialsService, FinancialsService>();

s.AddSingleton<ITicketRepository, TicketRepository>();
s.AddSingleton<IFoodRepository, FoodRepository>();

容器将根据注册的抽象及其实现来解决依赖关系。

如果您需要手动创建实例,则可以使用工厂委托来解决所需的依赖关系

//... assuming other dependencies already registered

s.AddSingleton<IFinancialsService>(sp => 
    new FinancialsService(
        sp.GetRequiredService<ITicketRepository>(),
        sp.GetRequiredService<IFoodRepository>()
    )
);

或使用ActivatorUtilities进行简化

//... assuming other dependencies already registered

s.AddSingleton<IFinancialsService>(sp => 
    ActivatorUtilities.CreateInstance<FinancialsService>(sp)
);

【讨论】:

我对这个问题的理解是,OP 希望创建一个 TicketService 的单例实例,该实例具有 ITicketRepository 作为依赖项。 哦,我会更新并添加注册详细信息。 谢谢恩科西。我最终使用了简化版本: s.AddSingleton(sp => ActivatorUtilities.CreateInstance(sp); ); 你能分享任何关于这个 ActivatorUtilities 或工厂代表的好读物吗?我找不到一个好的,因为我想很好地掌握它。感谢您的回复。 @SugarBowl 这里的答案提供了一些很好的信息。 ***.com/a/53884452/5233410

以上是关于具有多个接口作为构造函数中的参数的依赖注入的主要内容,如果未能解决你的问题,请参考以下文章

每日踩坑 2019-08-22 Unity 依赖注入 未能为类选择构造函数

当有多个实现接口的类时,如何指定构造函数注入[重复]

依赖注入:在无参数构造函数中实例化具体类时你会失去啥

laravel中的构造函数依赖注入理解

ASP.NET Core 依赖注入单个聚合类而不是多个单独的构造函数注入

Unity构造函数注入代码示例