[英]NServiceBus IUniformSession does not work with Azure WebJobs SDK
我無法讓 IUniformSession 在帶有通用主機的 Azure WebJobs SDK 項目中工作。 我正在使用 .NET 內置 DI。 我在下面創建了一個緊湊的復制品。
我在用
當類(“作業”)被實例化時,IUniformSession 被解析為依賴項。
IUniformSession 始終解析為 NULL。 一些快速斷言(如下所示)表明 IUniformSession 已在 DI 容器中注冊,因此 .EnableUniformSession() 正確執行此操作,但當請求實例時,它始終解析為 NULL。
csproj
<ItemGroup>
<PackageReference Include="Microsoft.Azure.WebJobs" Version="3.0.33" />
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions" Version="4.0.1" />
<PackageReference Include="Microsoft.Azure.WebJobs.Extensions.Storage" Version="5.0.1" />
<PackageReference Include="Microsoft.Azure.WebJobs.Host.Storage" Version="4.1.0" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="6.0.1" />
<PackageReference Include="NServiceBus" Version="7.7.4" />
<PackageReference Include="NServiceBus.Extensions.Hosting" Version="1.1.0" />
<PackageReference Include="NServiceBus.UniformSession" Version="2.2.0" />
<PackageReference Include="Serilog" Version="2.11.0" />
<PackageReference Include="Serilog.Extensions.Hosting" Version="5.0.1" />
<PackageReference Include="Serilog.Sinks.Console" Version="4.0.1" />
</ItemGroup>
程序.cs
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using NServiceBus;
using NServiceBus.UniformSession;
using NSUniformSessionRepro.DemoClasses;
using Serilog;
// Setup the ability to read config files
var configurationBuilder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
// then read the environment variables (in Azure) which will override some settings from the local settings
.AddEnvironmentVariables();
var configuration = configurationBuilder.Build();
var builder = new HostBuilder();
builder
.UseSerilog(Log.Logger)
.ConfigureAppConfiguration((context, config) =>
{
config.AddConfiguration(configuration);
})
.ConfigureWebJobs(b =>
{
b.AddAzureStorageCoreServices()
.AddAzureStorageBlobs()
.AddAzureStorageQueues()
.AddTimers();
});
IServiceCollection _serviceCollection = null;
builder.ConfigureServices(services =>
{
services.AddTransient<IMessagingService, MessagingService>();
_serviceCollection = services;
});
builder.UseNServiceBus(context =>
{
var endpointConfiguration = new EndpointConfiguration("MyEndpoint");
endpointConfiguration.EnableUniformSession();
endpointConfiguration.UseTransport<LearningTransport>();
endpointConfiguration.UsePersistence<LearningPersistence>();
// configure endpoint here
return endpointConfiguration;
});
var host = builder.Build();
var isUniformSessionRegistered = _serviceCollection.Any(x => x.ServiceType == typeof(IUniformSession));
Console.WriteLine("UniformSession is registered in DI: " + isUniformSessionRegistered);
using (host)
{
await host.RunAsync();
}
static void ConfigureLogging(IConfigurationRoot configuration)
{
var loggerConfiguration = new LoggerConfiguration()
.MinimumLevel.Information()
.WriteTo.Console();
Log.Logger = loggerConfiguration
.CreateLogger();
}
MessagingService.cs(只是一個虛擬的 class,它本身依賴於 IUniformSession)
public interface IMessagingService
{
// public for testing
IUniformSession UniformSession { get; set; }
Task Send(object message);
}
public class MessagingService : IMessagingService
{
// public for testing
public IUniformSession UniformSession { get; set; }
public MessagingService(IUniformSession uniformSession)
{
UniformSession = uniformSession;
}
public async Task Send(object message)
=> await UniformSession.Send(message);
}
演示工作
public class DemoJob
{
private readonly IMessagingService _messagingService;
public DemoJob(IMessagingService messagingService)
{
_messagingService = messagingService;
}
public void DummyJob([TimerTrigger("0 0 12 * * *", RunOnStartup = true, UseMonitor = false)] TimerInfo timer, TextWriter log)
{
// no-op
// for testing puporses
if (_messagingService.UniformSession == null)
Console.Write("UniformSession was NULL");
}
}
任何幫助將不勝感激。
這有點棘手,因為主機的設置方式會由於啟動順序而導致一些問題。
首先,我不確定您為什么要通過IMessagingService
在IUniformSession
上構建自己的抽象,所以我將把它省略掉。 請記住, IUniformSession
已經是IMessageSession
(這就是你在這里所需要的)和IMessageHandlerContext
的抽象。
您應該能夠通過在調用builder.UseNServiceBus
之前將調用移動到builder.ConfigureWebJobs
來依賴IUniformSession
或IMessageSession
,例如:
builder
.UseSerilog(Log.Logger)
.ConfigureAppConfiguration((context, config) =>
{
config.AddConfiguration(configuration);
})
.UseNServiceBus(context =>
{
var endpointConfiguration = new EndpointConfiguration("MyEndpoint");
endpointConfiguration.EnableUniformSession();
endpointConfiguration.UseTransport<LearningTransport>();
endpointConfiguration.UsePersistence<LearningPersistence>();
// configure endpoint here
return endpointConfiguration;
})
.ConfigureWebJobs(b =>
{
b.AddAzureStorageCoreServices()
.AddAzureStorageBlobs()
.AddAzureStorageQueues()
.AddTimers();
});
這將確保在 web 作業相關代碼之前配置和啟動 NServiceBus,以便可以在正確的時間點通過 DI 注入所需的服務。
請注意,使用IMessageSession
應該在前面指出這一點,因為 NServiceBus 通用主機支持具有顯式代碼來檢測統一 session 沒有的此類排序問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.