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

DefaultServiceSelector behavior change in v3.7.0 #207

Open
ArnaudB88 opened this issue Dec 14, 2023 · 3 comments
Open

DefaultServiceSelector behavior change in v3.7.0 #207

ArnaudB88 opened this issue Dec 14, 2023 · 3 comments

Comments

@ArnaudB88
Copy link

The DefaultServiceSelector value changed from (v3.6.3)
options.DefaultServiceSelector = serviceNames => serviceNames.SingleOrDefault(string.IsNullOrWhiteSpace) ?? serviceNames.Last();
to (v3.7.0)
options.DefaultServiceSelector = serviceNames => serviceNames.Last();

In the following scenario (dotnet7 asp.net core api project), the code to override registrations doesn't work anymore:
Program.cs

var builder = WebApplication.CreateBuilder(args);
builder.Host
    .UseLightInject()
    .ConfigureContainer<ServiceContainer>(container =>
    {
        ConfigureContainer(container);
        ConfigureServicesWithContainer(container, builder.Services);//Add services to the container.
    });
...

void ConfigureContainer(IServiceContainer container)
{
    //Bootstrap container
    //https://www.lightinject.net/#assembly-scanning
     var dllFilePaths = Directory.GetFiles(AppContext.BaseDirectory, "MyNamespace.*.dll");
     foreach (var dllFilePath in dllFilePaths)
      {
           var assembly = Assembly.LoadFrom(dllFilePath);
           container.RegisterAssembly(assembly);
      }

    //Add/override registrations
    container.RegisterSingleton<AppSettings>(factory => AppSettingsFactory.Create());
}

The assembly scanning method will register the type 'AppSettings' with servicename "MyNamespace.AppSettings".
The explicit singleton registration with factory afterwards, will register the type 'AppSettings' without a servicename.

When resolving the type, the following instances are returned;

  • v3.6.3: instance of registered type without a servicename (so the last 'override 'registration, lifetime PerContainer)
  • v3.7.0: instance of registered type with a namespace (so the original registration from the assembly scanning, lifetime null)

This change in default behavior can't be used in all our projects since we rely on explicit overrides after assembly scanning.

Why was this change of behavior done? Is it possible that you changed it because you wanted registrations on the serviceCollection to be returned prior to registrations of the same type on the container (I say this based on the added unit tests).
Can you change the behavior again so explicit registrations are returned prior to assembly scanned registrations?

@ArnaudB88
Copy link
Author

@seesharper Can you please take a look at this? It prevents us from using the latest version

@ArnaudB88
Copy link
Author

@seesharper Is the LightInject project abandoned?

@seesharper
Copy link
Owner

Sorry for the very late reply.
The reason for this was that most users use LightInject as a drop-in replacement for the built-in container from Microsoft.
Overriding services is in most cases done through the IServiceCollection which Microsoft provides.
LightInject uses some tricks with the service names to make sure that we stay 100% compatible with MS.DI.
This is not by any means ideal and now that MS.DI also supports named services, this becomes even worse.
So in order to support MS.DI without the "hacks" , work has started to make some changes to LightInject that makes it possible to be compatible without using the service name as a way to hack this through.
Would it be an acceptable workaround to override services via IServiceCollection rather than through IServiceRegistry?

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

No branches or pull requests

2 participants