.NET Core 内置依赖注入 (DI):如何不新建依赖项?

Posted

技术标签:

【中文标题】.NET Core 内置依赖注入 (DI):如何不新建依赖项?【英文标题】:.NET Core Built In Dependency Injection (DI): How can I not new up Dependencies? 【发布时间】:2022-01-24 01:28:07 【问题描述】:

我目前正在使用 .NET Core 内置的依赖注入 (DI)。

我的应用程序正在使用规则引擎设计模式。

我的一条规则,有一个依赖,它有一个依赖。所以,我必须继续“更新”依赖项的实例。我觉得好像有更好的方法。

这是我的代码示例。

这可行,但我不喜欢我必须新建 DataService 和存储库。

var rules = new List<IRule>
   
      new Rule1(),
      new Rule2(new DataService(new Repository(CnnStr))) //This is what I don't like
   ;
s.AddTransient<IRulesEngine>(sp => new RulesEngine(rules));

我开始设置这个:

s.AddTransient<IRepository>(sp => new Repository(CnnStr));
s.AddTransient<IDataService>(sp => sp.GetRequiredService<DataService>());

这似乎让我更接近我想要的。但是,我不知道如何用规则实例列表填充规则列表,而不必新建依赖项(DataService 和 Repo)。

类似这样,但我知道这段代码不对。

var rules = new List<IRule>
   
      s.AddTransient<IRule>(sp => sp.GetRequiredService<Rule1>())
      s.AddTransient<IRule>(sp => sp.GetRequiredService<Rule2>())
   ;
s.AddTransient<IRulesEngine>(sp => new RulesEngine(rules));

任何帮助将不胜感激。

谢谢。

【问题讨论】:

相关:***.com/questions/39567609/… s.AddTransient&lt;IRule, Rule&gt;(); s.AddTransient&lt;IRulesEngine,RulesEngine&gt;(); 应该只要RulesEngine 接受IEnumerable&lt;IRule&gt; 就可以工作。不知道你为什么要把一切都搞得过于复杂。 @JeremyLakeman 感谢您的回复,但我认为您并不完全了解情况(或者我误解了您的建议)。我做不到:s.AddTransient();或者至少我认为我做不到,因为我有 2 条规则(实际上我将有大约 20 条规则)。所有规则都实现了 IRule,但都有不同的功能。您熟悉规则引擎设计模式吗? @DanielA.White 谢谢,我会在早上查看这个链接。 并且默认的 DI 容器将 IEnumerable&lt;&gt; 注册为一个开放的泛型。任何具有可枚举构造函数参数的服务都将接收所有已注册的服务。 【参考方案1】:

注册依赖,规则需要

s.AddTransient<IRepository>(sp => new Repository(CnnStr));
s.AddTransient<IDataService, DataService>(); // you don't need sp here

然后注册规则。 TryAddEnumerable 确保不会有相同接口的重复实现

s.TryAddEnumerable(new[] 
  ServiceDescriptor.Transient<IRule, Rule1>();
  ServiceDescriptor.Transient<IRule, Rule2>();
);

注册规则引擎

s.AddTransient<IRulesEngine, RulesEngine>();

注意规则引擎应该依赖于IEnumerable&lt;IRule&gt;

【讨论】:

谢谢。我会在早上尝试这第一件事。【参考方案2】:

我今天早上开始工作了。

我从很多回复中使用了一点。但是,@Daniel A. White 建议的下面的链接对我来说是所有这些。

.NET Core dependency injection -> Get all implementations of an interface

也许我像@Jeremey Lakeman 建议的那样过于复杂。

这是我在 Program.cs 文件中所做的更改:

s.AddTransient<IRepository>(sp => new Repository(CnnStr));
s.AddTransient<IDataService, DataService>();

s.AddTransient<IRule, Rule1>();
s.AddTransient<IRule, Rule2>();

s.AddTransient<IRulesEngine, RulesEngine>();

加上我对规则引擎所做的更改:

private readonly IEnumerable<IRule> _rules;

public RulesEngine(IEnumerable<IRule> rules)
   
      _rules = rules;
   

public void RunRules()
      
      foreach (var rule in _rules)
      
         rule.Execute(canonical);
                  
   

【讨论】:

以上是关于.NET Core 内置依赖注入 (DI):如何不新建依赖项?的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET Core Web 应用程序系列- 使用ASP.NET Core内置的IoC容器DI进行批量依赖注入(MVC当中应用)

ASP.NET Core 依赖注入(DI)

ASP.NET Core Web 应用程序系列- 在ASP.NET Core中使用Autofac替换自带DI进行批量依赖注入(MVC当中应用)

ASP.NET Core中的依赖注入:依赖注入(DI)

ASP.NET Core Web 应用程序系列- 在ASP.NET Core中使用Autofac替换自带DI进行构造函数和属性的批量依赖注入(MVC当中应用)

ASP.NET Core学习——6