Ev.ServiceBus
Ev.ServiceBus copied to clipboard
Fix ServiceDescriptor access for keyed services
Fixes issue where System.InvalidOperationException: 'This service descriptor is keyed. Your service provider may not support keyed services.'
is thrown during startup if keyed services are registered.
Hi. Can you give me some details on how to reproduce this bug you are trying to fix ?
Here is a sample that should reproduce the issue I'm seeing.
<ItemGroup>
<PackageReference Include="Ev.ServiceBus" Version="5.0.1" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>
using Azure.Messaging.ServiceBus;
using Ev.ServiceBus.Abstractions;
using Microsoft.Extensions.Hosting;
using System.Text;
using Ev.ServiceBus;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;
using var host = new HostBuilder()
.ConfigureServices(services =>
{
services.AddKeyedSingleton<INotificationService, SmsNotificationService>("sms");
services.AddKeyedSingleton<INotificationService, EmailNotificationService>("email");
services.AddServiceBus(
settings =>
{
settings.WithConnection("string", new ServiceBusClientOptions());
})
.WithPayloadSerializer<MessagePayloadSerializer>();
services.RegisterServiceBusDispatch().ToQueue("ServiceBusResources.MyQueue", builder =>
{
builder.RegisterDispatch<WeatherForecast[]>();
});
})
.Build();
await host.StartAsync();
[Serializable]
public class WeatherForecast
{
}
public class MessagePayloadSerializer : IMessagePayloadSerializer
{
private static readonly JsonSerializerSettings Settings = new()
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
Formatting = Formatting.None,
Converters =
{
new StringEnumConverter()
},
NullValueHandling = NullValueHandling.Ignore
};
public SerializationResult SerializeBody(object objectToSerialize)
{
var json = JsonConvert.SerializeObject(objectToSerialize, Formatting.None, Settings);
return new SerializationResult("application/json", Encoding.UTF8.GetBytes(json));
}
public object DeSerializeBody(byte[] content, Type typeToCreate)
{
var @string = Encoding.UTF8.GetString(content);
return JsonConvert.DeserializeObject(@string, typeToCreate, Settings)!;
}
}
public interface INotificationService
{
string Notify(string message);
}
public class SmsNotificationService : INotificationService
{
public string Notify(string message) => $"[SMS] {message}";
}
public class EmailNotificationService : INotificationService
{
public string Notify(string message) => $"[Email] {message}";
}