Skip to content

Conversation

@amcorch
Copy link

@amcorch amcorch commented Apr 4, 2024

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.

@benspeth
Copy link
Member

benspeth commented Apr 9, 2024

Hi.
Can you give me some details on how to reproduce this bug you are trying to fix ?

@amcorch
Copy link
Author

amcorch commented Apr 9, 2024

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}";
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants