Skip to content

Commit

Permalink
proper replace
Browse files Browse the repository at this point in the history
  • Loading branch information
sungam3r committed Jan 3, 2024
1 parent b03592f commit 1ced9fc
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 2 deletions.
43 changes: 43 additions & 0 deletions src/SteroidsDI.Tests/Cases/FactoryTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,49 @@ public void Named_Binding_Should_Throw_On_Unknown_Lifetime()
Use the 'Named'/'Default' overloads with explicit Lifetime or first register 'SteroidsDI.Tests.IBuilder' in the DI container.");
}

[Test]
public void Named_Binding_Should_Allow_The_Same_Type_With_Different_Names()
{
var services = new ServiceCollection()
.AddTransient<IBuilder, Builder>()
.For<IBuilder>()
.Named<SpecialBuilder>("aaa")
.Named<SpecialBuilder>("bbb")
.Named<SpecialBuilder>("ccc")
.Services;
services.Count.ShouldBe(5);
}

[Test]
public void Default_Binding_Should_Allow_Redeclaration()
{
var services = new ServiceCollection()
.AddTransient<IBuilder, Builder>()
.For<IBuilder>()
.Default<SpecialBuilder>()
.Default<SpecialBuilder>()
.Services;
services.Count.ShouldBe(3);
var def = (NamedBinding)services.Last().ImplementationInstance!;
def.Name.ShouldBeNull();
def.ImplementationType.ShouldBe(typeof(SpecialBuilder));
}

[Test]
public void Default_Binding_Should_Allow_Replace()
{
var services = new ServiceCollection()
.AddTransient<IBuilder, Builder>()
.For<IBuilder>()
.Default<SpecialBuilder>()
.Default<SpecialBuilderOver9000Level>()
.Services;
services.Count.ShouldBe(4);
var def = (NamedBinding)services[2].ImplementationInstance!;
def.Name.ShouldBeNull();
def.ImplementationType.ShouldBe(typeof(SpecialBuilderOver9000Level));
}

[Test]
[TestCase(true)]
[TestCase(false)]
Expand Down
13 changes: 12 additions & 1 deletion src/SteroidsDI/Factory/BindingContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,18 @@ public BindingContext<TService> Default<TImplementation>(ServiceLifetime lifetim
if (existing == null)
Services.Add(new ServiceDescriptor(typeof(TImplementation), typeof(TImplementation), lifetime));

Services.AddSingleton(new NamedBinding(null, typeof(TService), typeof(TImplementation)));
var def = new NamedBinding(null, typeof(TService), typeof(TImplementation));
var descriptor = ServiceDescriptor.Singleton(def);
for (int i = 0; i < Services.Count; ++i)
{
if (Services[i].ImplementationInstance is NamedBinding named && named.Name is null && named.ServiceType == typeof(TService))
{
Services[i] = descriptor;
return this;
}
}

Services.Add(descriptor);

return this;
}
Expand Down
2 changes: 1 addition & 1 deletion src/SteroidsDI/Factory/NamedBinding.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace SteroidsDI;
/// type <see cref="ImplementationType" /> in the required context.
/// </summary>
[DebuggerDisplay("{Name}: {ServiceType.Name} -> {ImplementationType.Name}")]
internal sealed class NamedBinding
internal sealed record NamedBinding
{
public NamedBinding(object? name, Type serviceType, Type implementationType)
{
Expand Down

0 comments on commit 1ced9fc

Please sign in to comment.