Jon*_*ark 8 c# dependency-injection .net-core
我一直在尝试掌握 .NET Core 中依赖注入的概念,但遇到了问题。我想我在某处遗漏了要点。
举个例子,假设我有一个顶级GameHandler类,然后是一个Game类和一个ScoreCard类。
我的Game类依赖于ScoreCard类,并且需要将其注册为临时服务,因为每个新游戏都需要一个新的记分卡。我可以通过这样做来实现这一目标......
public class Game
{
private readonly IScoreCard _scoreCard;
public Game(IScoreCard scoreCard)
{
_scoreCard = scoreCard;
}
}
Run Code Online (Sandbox Code Playgroud)
然后我在startup.cs中的ConfigureServices方法中注册服务
services.AddTransient<IScoreCard, ScoreCard>();
Run Code Online (Sandbox Code Playgroud)
这一切都很好,这是一个简单的一对一关系,其中Game类需要ScoreCard类的单个实例。
我的GameHandler类也依赖于Game类。然而,在这种情况下,我希望可能有多个游戏,可能与密钥一起存储在某种字典中。而且我不知道需要多少个,因为这取决于谁在特定时间玩游戏,所以我需要在需要时创建新的游戏对象。
如果我尝试使用new来执行此操作,就像这样
Game _newGame = new Game();
Run Code Online (Sandbox Code Playgroud)
它显然不起作用,因为我的游戏构造函数现在有 DI 记分卡内容,并且不匹配。那么如何使用 DI 创建 Game 的新实例而不使用new呢?
在某些时候,您需要一个“范围”。该范围是代码中创建实例的级别。在某些情况下,范围可能是main,在消息传递系统中,每个“消息”将具有新的范围。
如果您的范围是“每次创建新游戏时”,然后使用您正在使用的任何 DI 包(我猜这是默认的网络核心包),那么您需要调用IServiceProvider.CreateScope(). 此后,任何时候您要求服务提供商为您提供一个新的 Game(),它都会根据每个类的注册方式返回一个。
使用依赖注入,您永远不应该调用new,您需要要求服务提供者为您提供类型的实例。
IServiceProvider.GetService<YourType>();
Run Code Online (Sandbox Code Playgroud)
IServiceProvider 可以在您创建它时(注册和构建之后)进行检索,也可以实际上将其注入到构造函数中。