Skip to content

Commit

Permalink
Allow services to be overridden using ServiceCollection
Browse files Browse the repository at this point in the history
  • Loading branch information
seesharper committed Apr 27, 2023
1 parent 54404d9 commit a719a97
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
using System;
using Microsoft.Extensions.DependencyInjection;
using Xunit;

namespace LightInject.Microsoft.DependencyInjection.Tests;

public class DefaultServiceTests
{
[Fact]
public void ShouldOverrideDefaultRegistrationInServiceContainer()
{
var container = new ServiceContainer(options => options.WithMicrosoftSettings());
container.RegisterTransient<IFoo, Foo>();
var serviceCollection = new ServiceCollection();

serviceCollection.AddSingleton<IFoo, AnotherFoo>();

var provider = container.CreateServiceProvider(serviceCollection);

var foo = provider.GetRequiredService<IFoo>();

Assert.IsType<AnotherFoo>(foo);
}

[Fact]
public void ShouldOverrideNamedRegistrationInServiceContainer()
{
var container = new ServiceContainer(options => options.WithMicrosoftSettings());
container.RegisterTransient<IFoo, Foo>("Foo");
var serviceCollection = new ServiceCollection();

serviceCollection.AddSingleton<IFoo, AnotherFoo>();

var provider = container.CreateServiceProvider(serviceCollection);

var foo = provider.GetRequiredService<IFoo>();

Assert.IsType<AnotherFoo>(foo);
}

[Fact]
public void ShouldOverrideMultipleNamedRegistrationInServiceContainer()
{
var container = new ServiceContainer(options => options.WithMicrosoftSettings());
container.RegisterTransient<IFoo, Foo>("Foo1");
container.RegisterTransient<IFoo, Foo>("Foo2");
var serviceCollection = new ServiceCollection();

serviceCollection.AddSingleton<IFoo, AnotherFoo>();

var provider = container.CreateServiceProvider(serviceCollection);

var foo = provider.GetRequiredService<IFoo>();

Assert.IsType<AnotherFoo>(foo);
}

[Fact]
public void ShouldOverrideNamedAndDefaultRegistrationInServiceContainer()
{
var container = new ServiceContainer(options => options.WithMicrosoftSettings());
container.RegisterTransient<IFoo, Foo>();
container.RegisterTransient<IFoo, Foo>("Foo");
var serviceCollection = new ServiceCollection();

serviceCollection.AddSingleton<IFoo, AnotherFoo>();

var provider = container.CreateServiceProvider(serviceCollection);

var foo = provider.GetRequiredService<IFoo>();

Assert.IsType<AnotherFoo>(foo);
}


[Fact]
public void ShouldUseLast()
{
var container = new ServiceContainer(options => options.WithMicrosoftSettings());
container.RegisterTransient<IFoo, Foo>("Foo1");
container.RegisterTransient<IFoo, Foo>("Foo2");
var serviceCollection = new ServiceCollection();

serviceCollection.AddSingleton<IFoo, AnotherFoo>();

var provider = container.CreateServiceProvider(serviceCollection);

var foo = provider.GetRequiredService<IFoo>();

Assert.IsType<AnotherFoo>(foo);
}

public interface IFoo { }

public class Foo : IFoo { }

public class AnotherFoo : IFoo { }
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Extensions.DependencyInjection;
using Xunit;
Expand Down Expand Up @@ -92,7 +93,7 @@ public void ShouldPickServiceWithoutServiceNameAsDefaultIfRegistered()
{
var serviceCollection = new ServiceCollection();
serviceCollection.AddTransient<string>(p => "42");
var factory = new LightInjectServiceProviderFactory();
var factory = new LightInjectServiceProviderFactory(options => options.DefaultServiceSelector = serviceNames => serviceNames.SingleOrDefault(string.IsNullOrWhiteSpace) ?? serviceNames.Last());
var container = factory.CreateBuilder(serviceCollection);

container.Register<string>(f => "84");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,10 +119,24 @@ private static void RegisterServices(IServiceContainer container, Scope rootScop
{
var registrations = serviceCollection.Select(d => CreateServiceRegistration(d, rootScope)).ToList();

var servicesThatRequireNamePrefix = container.AvailableServices
.GroupBy(si => si.ServiceType)
.Select(g => new { ServiceType = g.Key, Prefix = g.OrderBy(g => g.ServiceName).Last().ServiceName })
.ToDictionary(g => g.ServiceType, g => g.Prefix);

Check warning on line 126 in src/LightInject.Microsoft.DependencyInjection/LightInject.Microsoft.DependencyInjection.cs

View workflow job for this annotation

GitHub Actions / build

Code should not contain multiple blank lines in a row

Check warning on line 126 in src/LightInject.Microsoft.DependencyInjection/LightInject.Microsoft.DependencyInjection.cs

View workflow job for this annotation

GitHub Actions / build

Code should not contain multiple blank lines in a row

Check warning on line 126 in src/LightInject.Microsoft.DependencyInjection/LightInject.Microsoft.DependencyInjection.cs

View workflow job for this annotation

GitHub Actions / build

Code should not contain multiple blank lines in a row

Check warning on line 126 in src/LightInject.Microsoft.DependencyInjection/LightInject.Microsoft.DependencyInjection.cs

View workflow job for this annotation

GitHub Actions / build

Code should not contain multiple blank lines in a row

Check warning on line 126 in src/LightInject.Microsoft.DependencyInjection/LightInject.Microsoft.DependencyInjection.cs

View workflow job for this annotation

GitHub Actions / build

Code should not contain multiple blank lines in a row

Check warning on line 126 in src/LightInject.Microsoft.DependencyInjection/LightInject.Microsoft.DependencyInjection.cs

View workflow job for this annotation

GitHub Actions / build

Code should not contain multiple blank lines in a row


for (int i = 0; i < registrations.Count; i++)
{
ServiceRegistration registration = registrations[i];
registration.ServiceName = i.ToString("D8", CultureInfo.InvariantCulture.NumberFormat);
if (servicesThatRequireNamePrefix.TryGetValue(registration.ServiceType, out string prefix))
{
registration.ServiceName = prefix + i.ToString("D8", CultureInfo.InvariantCulture.NumberFormat);
}
else
{
registration.ServiceName = i.ToString("D8", CultureInfo.InvariantCulture.NumberFormat);
}

Check warning on line 139 in src/LightInject.Microsoft.DependencyInjection/LightInject.Microsoft.DependencyInjection.cs

View workflow job for this annotation

GitHub Actions / build

Closing brace should be followed by blank line

Check warning on line 139 in src/LightInject.Microsoft.DependencyInjection/LightInject.Microsoft.DependencyInjection.cs

View workflow job for this annotation

GitHub Actions / build

Closing brace should be followed by blank line

Check warning on line 139 in src/LightInject.Microsoft.DependencyInjection/LightInject.Microsoft.DependencyInjection.cs

View workflow job for this annotation

GitHub Actions / build

Closing brace should be followed by blank line

Check warning on line 139 in src/LightInject.Microsoft.DependencyInjection/LightInject.Microsoft.DependencyInjection.cs

View workflow job for this annotation

GitHub Actions / build

Closing brace should be followed by blank line

Check warning on line 139 in src/LightInject.Microsoft.DependencyInjection/LightInject.Microsoft.DependencyInjection.cs

View workflow job for this annotation

GitHub Actions / build

Closing brace should be followed by blank line

Check warning on line 139 in src/LightInject.Microsoft.DependencyInjection/LightInject.Microsoft.DependencyInjection.cs

View workflow job for this annotation

GitHub Actions / build

Closing brace should be followed by blank line
container.Register(registration);
}
}
Expand Down Expand Up @@ -234,7 +248,8 @@ public static class ContainerOptionsExtensions
/// <returns><see cref="ContainerOptions"/>.</returns>
public static ContainerOptions WithMicrosoftSettings(this ContainerOptions options)
{
options.DefaultServiceSelector = serviceNames => serviceNames.SingleOrDefault(string.IsNullOrWhiteSpace) ?? serviceNames.Last();
//options.DefaultServiceSelector = serviceNames => serviceNames.SingleOrDefault(string.IsNullOrWhiteSpace) ?? serviceNames.Last();

Check warning on line 251 in src/LightInject.Microsoft.DependencyInjection/LightInject.Microsoft.DependencyInjection.cs

View workflow job for this annotation

GitHub Actions / build

Single line comment should begin with a space

Check warning on line 251 in src/LightInject.Microsoft.DependencyInjection/LightInject.Microsoft.DependencyInjection.cs

View workflow job for this annotation

GitHub Actions / build

Single line comment should begin with a space

Check warning on line 251 in src/LightInject.Microsoft.DependencyInjection/LightInject.Microsoft.DependencyInjection.cs

View workflow job for this annotation

GitHub Actions / build

Single line comment should begin with a space

Check warning on line 251 in src/LightInject.Microsoft.DependencyInjection/LightInject.Microsoft.DependencyInjection.cs

View workflow job for this annotation

GitHub Actions / build

Single line comment should begin with a space
options.DefaultServiceSelector = serviceNames => serviceNames.Last();
options.EnablePropertyInjection = false;
options.EnableCurrentScope = false;
options.EnableOptionalArguments = true;
Expand Down

0 comments on commit a719a97

Please sign in to comment.