首先,我应该说我一直是一个 VB.Net 爱好者程序员,所以请对 C# 保持温和!
我有一个 .NET 4.8 Windows 服务,在我的应用程序中自托管一个 SignalR 集线器,运行良好(感谢 Rick Strahl 的精彩示例)。
我想将此服务迁移到更多平台不可知的服务,.NET Core Worker Service 似乎是理想的选择,但在 Vs2019 中没有 VB.Net 模板(仅 C#),所以我正在冒险进入新领域并学习哪个有助于开发真实用例。
下面的代码基本上是嫁接了SignalR的OOTB工作服务模板的稻草人;我还没有真正掌握基础知识。
它编译正常,没有错误,但是当我尝试在 VS 中调试时,我得到了这个错误,尽管在本网站和其他网站上查找了许多这样做的例子,但它让我难倒;据我所知,我已经像其他人一样对其进行了编码,但它在 CreateHostBuilder 行上失败了?
System.AggregateException
HResult=0x80131500
Message=Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: Microsoft.Extensions.Hosting.IHostedService Lifetime: Singleton ImplementationType: ModbusWorkerService.ModbusWorker': Unable to resolve service for type 'Microsoft.AspNetCore.SignalR.IHubContext`2[ModbusWorkerService.ModbusHub,ModbusWorkerService.IModbus]' while attempting to activate 'ModbusWorkerService.ModbusWorker'.)
Source=Microsoft.Extensions.DependencyInjection
StackTrace:
at Microsoft.Extensions.DependencyInjection.ServiceProvider..ctor(IEnumerable`1 serviceDescriptors, IServiceProviderEngine engine, ServiceProviderOptions options)
at Microsoft.Extensions.DependencyInjection.ServiceCollectionContainerBuilderExtensions.BuildServiceProvider(IServiceCollection services, ServiceProviderOptions options)
at Microsoft.Extensions.DependencyInjection.DefaultServiceProviderFactory.CreateServiceProvider(IServiceCollection containerBuilder)
at Microsoft.Extensions.Hosting.Internal.ServiceFactoryAdapter`1.CreateServiceProvider(Object containerBuilder)
at Microsoft.Extensions.Hosting.HostBuilder.CreateServiceProvider()
at Microsoft.Extensions.Hosting.HostBuilder.Build()
at ModbusWorkerService.Program.Main(String[] args) in D:\Development\Comfort\Plugins\Modbus\ModbusWorkerService\Program.cs:line 12
This exception was originally thrown at this call stack:
[External Code]
Inner Exception 1:
InvalidOperationException: Error while validating the service descriptor 'ServiceType: Microsoft.Extensions.Hosting.IHostedService Lifetime: Singleton ImplementationType: ModbusWorkerService.ModbusWorker': Unable to resolve service for type 'Microsoft.AspNetCore.SignalR.IHubContext`2[ModbusWorkerService.ModbusHub,ModbusWorkerService.IModbus]' while attempting to activate 'ModbusWorkerService.ModbusWorker'.
Inner Exception 2:
InvalidOperationException: Unable to resolve service for type 'Microsoft.AspNetCore.SignalR.IHubContext`2[ModbusWorkerService.ModbusHub,ModbusWorkerService.IModbus]' while attempting to activate 'ModbusWorkerService.ModbusWorker'.
这可能是我在 c# 方面的经验不足(因为 VB.Net 中的 DI 对我来说是第二天性),但任何人都可以就我做错的事情向我提供任何指导。
代码如下。
问候
朱利安
这里是 Program.cs
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace ModbusWorkerService
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args)
.Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureServices((hostContext, services) =>
{
services.AddHostedService<ModbusWorker>();
});
}
public class Startup
{
public static void ConfigureServices(IServiceCollection services)
{
services.AddSignalR();
services.AddHostedService<ModbusWorker>();
}
public static void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapHub<ModbusHub>("/hubs/Modbus");
});
}
}
}
这是我的工作人员:
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using System.Threading;
using System.Threading.Tasks;
namespace ModbusWorkerService
{
public class ModbusWorker : BackgroundService
{
private readonly ILogger<ModbusWorker> _logger;
private readonly IHubContext<ModbusHub, IModbus> _ModbusHub;
public ModbusWorker(ILogger<ModbusWorker> logger, IHubContext<ModbusHub, IModbus> ModbusHub)
{
_logger = logger;
_ModbusHub = ModbusHub;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
await _ModbusHub.Clients.All.ShowTime(DateTime.Now);
await Task.Delay(1000, stoppingToken);
}
}
}
}
最后是我的 SignalR 集线器:
using System;
using System.Threading.Tasks;
using System.Collections.Concurrent;
using Microsoft.AspNetCore.SignalR;
namespace ModbusWorkerService
{
public class ModbusHub : Hub<IModbus>
{
public static ConcurrentDictionary<string, string> ConnectedUsers = new ConcurrentDictionary<string, string>();
//public static BackgroundService HubHost;
[HubMethodName("SendMessage")]
public async Task SendMessage(string user)
{
await Clients.All.SendAsync("ReceiveGreeting", $"Good Morning {user}");
}
public override async Task OnConnectedAsync()
{
string ClientID = GetClientID();
string HostName = GetHostName();
if (!ConnectedUsers.ContainsKey(ClientID))
ConnectedUsers.TryAdd(ClientID, HostName);
// Clients.All.ShowUsersOnLine(ConnectedUsers.Count);
await base.OnConnectedAsync();
}
public override async Task OnDisconnectedAsync(Exception exception)
{
string ClientID = GetClientID();
if (ConnectedUsers.ContainsKey(ClientID))
ConnectedUsers.TryRemove(ClientID, out _);
// Clients.All.ShowUsersOnLine(ConnectedUsers.Count);
await base.OnDisconnectedAsync(exception);
}
private string GetClientID()
{
string ClientID = "";
//if (!(Context.QueryString['ClientID'] == null))
// // ClientID passed from application
// ClientID = Context.QueryString['ClientID'].ToString();
if (ClientID.Trim() == "")
ClientID = Context.ConnectionId;
return ClientID;
}
private string GetHostName()
{
string HostName = "";
//if (!(Context.QueryString['HostName'] == null))
// // ClientID passed from application
// HostName = Context.QueryString['HostName'].ToString();
if (HostName.Trim() == "")
HostName = "Not Known";
return HostName;
}
}
public interface IModbus
{
Task ShowTime(DateTime currentTime);
Task SendAsync(string Method, string Values);
}
}
答案 0 :(得分:0)
我想你忘记使用启动了。
替换 program.cs 中的以下几行
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureServices((hostContext, services) =>
{
services.AddHostedService<ModbusWorker>();
});
到
public static IHostBuilder CreateWebHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); });