【发布时间】:2019-08-24 23:12:57
【问题描述】:
我正在与一个奇怪的案例作斗争。我有一个这样设置的 .NET Core 控制台应用程序:
private static async Task Main(string[] args)
{
var runAsService = !(Debugger.IsAttached || args.Contains("console"));
var builder = new HostBuilder()
.ConfigureServices((hostContext, services) =>
{
services.AddLogging(loggingBuilder => { loggingBuilder.AddConsole(); });
services.AddGatewayServers();
services.AddHostedService<GatewayService>();
});
if (runAsService)
await builder.RunServiceAsync();
else
await builder.RunConsoleAsync();
}
然后我在IServiceCollection 上有扩展,设置AddGatewayServers() 如下:
public static void AddGatewayServers(this IServiceCollection services)
{
services.AddTransient<IGatewayServer, Server1>();
services.AddTransient<IGatewayServer, Server2>();
services.AddTransient<Func<ServerType, IGatewayServer>>(provider => key =>
{
switch (key)
{
case ServerType.Type1: return provider.GetService<Server1>();
case ServerType.Type2: return provider.GetService<Server2>();
default: return null;
}
});
}
然后在我的课堂上注入这样的依赖:
private readonly Func<ServerType, IGatewayServer> _gatewayAccessor;
public GatewayServerCollection(Func<ServerType, IGatewayServer> gatewayAccessor)
{
_gatewayAccessor = gatewayAccessor;
}
但是当我稍后在GatewayServerCollection 中调用_gatewayAccessor 以获取IGatewayServer 的实例时,它返回null。我这样称呼它:
var server = _gatewayAccessor(ServerType.Type1);
我错过了什么?
【问题讨论】:
-
将
AddGatewayServers方法内的GetService<T>调用改为GetRequiredService<T>,然后重试。 -
您不需要使函数成为临时依赖项。它不会从一个执行程序更改为下一个执行程序
-
感谢@Steven 的评论。已经试过了。我得到了异常(因为如果找不到注册,GetRequiredService 方法应该抛出)
-
@Jinish:没错!您使用
IGatewayServer服务类型注册了这些类型。这意味着您可以仅按该类型解决它。你应该用它们的具体类型来注册它们。 -
感谢@Steven 注意到这一点。就是这样。我完全忽略了将类型注册为 IGatewayServer 的这一点。将它们注册为具体类型解决了这个问题(并且非常有意义)。谢谢。如果您将其添加为答案,我将很乐意将其标记为
标签: c# dependency-injection .net-core .net-core-2.2