Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix ServiceDescriptor access for keyed services #71

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

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.

None yet

3 participants