Skip to content

Commit 439a94a

Browse files
add support for keyed required service
1 parent 6ed4084 commit 439a94a

File tree

2 files changed

+74
-2
lines changed

2 files changed

+74
-2
lines changed

src/Ninject.Web.AspNetCore.Test/Unit/ServiceProviderKeyedTest.cs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,71 @@ public void ExistingMultipleServices_ResolvesNonKeyedToNull()
7878
provider.GetService(typeof(IWarrior)).Should().BeNull();
7979
}
8080

81+
[Fact]
82+
public void RequiredKeyedServiceCollectionExisting_CorrectServiceResolved()
83+
{
84+
var collection = new ServiceCollection();
85+
collection.Add(new ServiceDescriptor(typeof(IWarrior),"Samurai", typeof(Samurai), ServiceLifetime.Transient));
86+
collection.Add(new ServiceDescriptor(typeof(IWarrior), "Ninja", new Ninja("test")));
87+
var kernel = CreateTestKernel(collection);
88+
var provider = CreateServiceProvider(kernel);
89+
90+
provider.GetRequiredKeyedService(typeof(IWarrior), "Ninja").Should().NotBeNull().And.BeOfType(typeof(Ninja));
91+
provider.GetRequiredKeyedService(typeof(IWarrior), "Samurai").Should().NotBeNull().And.BeOfType(typeof(Samurai));
92+
93+
}
94+
95+
[Fact]
96+
public void RequiredKeyedNinjectDirectBindingExisting_CorrectServiceResolved()
97+
{
98+
var kernel = CreateTestKernel();
99+
kernel.Bind<IWarrior>().To<Samurai>().WithMetadata(nameof(ServiceKey), new ServiceKey("Samurai"));
100+
kernel.Bind<IWarrior>().ToConstant(new Ninja("test")).WithMetadata(nameof(ServiceKey), new ServiceKey("Ninja"));
101+
var provider = CreateServiceProvider(kernel);
102+
103+
provider.GetRequiredKeyedService(typeof(IWarrior), "Samurai").Should().NotBeNull().And.BeOfType(typeof(Samurai));
104+
provider.GetRequiredKeyedService(typeof(IWarrior), "Ninja").Should().NotBeNull().And.BeOfType(typeof(Ninja));
105+
}
106+
107+
[Fact]
108+
public void RequiredKeyedNonExisting_SingleServiceResolvedToException()
109+
{
110+
var kernel = CreateTestKernel();
111+
var provider = CreateServiceProvider(kernel);
112+
113+
Action action = () => provider.GetRequiredKeyedService(typeof(IWarrior), "Samurai");
114+
action.Should().Throw<ActivationException>().WithMessage("*No matching bindings are available*");
115+
}
116+
117+
[Fact]
118+
public void RequiredExistingMultipleKeydServices_ResolvedQueriedAsList()
119+
{
120+
var kernel = CreateTestKernel();
121+
kernel.Bind<IWarrior>().To<Samurai>().WithMetadata(nameof(ServiceKey), new ServiceKey("Samurai"));;
122+
kernel.Bind<IWarrior>().ToConstant(new Ninja("test")).WithMetadata(nameof(ServiceKey), new ServiceKey("Ninja"));
123+
var provider = CreateServiceProvider(kernel);
124+
125+
var result = provider.GetRequiredService(typeof(IList<IWarrior>)) as IEnumerable<IWarrior>;
126+
127+
result.Should().NotBeNull();
128+
var resultList = result.ToList();
129+
resultList.Should().HaveCount(2);
130+
resultList.Should().Contain(x => x is Samurai);
131+
resultList.Should().Contain(x => x is Ninja);
132+
}
133+
134+
[Fact]
135+
public void ExistingMultipleServices_ResolvesNonKeyedToException()
136+
{
137+
var kernel = CreateTestKernel();
138+
kernel.Bind<IWarrior>().To<Samurai>().WithMetadata(nameof(ServiceKey), new ServiceKey("Samurai"));;
139+
kernel.Bind<IWarrior>().ToConstant(new Ninja("test")).WithMetadata(nameof(ServiceKey), new ServiceKey("Ninja"));
140+
var provider = CreateServiceProvider(kernel);
141+
142+
Action action = () => provider.GetRequiredService(typeof(IWarrior));
143+
action.Should().Throw<ActivationException>().WithMessage("*More than one matching bindings are available*");
144+
}
145+
81146
private IServiceProvider CreateServiceProvider(AspNetCoreKernel kernel)
82147
{
83148
NinjectServiceProviderBuilder builder = CreateServiceProviderBuilder(kernel);

src/Ninject.Web.AspNetCore/NinjectServiceProvider.cs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using Microsoft.Extensions.DependencyInjection;
22
using Ninject.Syntax;
33
using System;
4+
using Ninject.Planning.Bindings;
45

56
namespace Ninject.Web.AspNetCore
67
{
@@ -52,12 +53,18 @@ public void Dispose()
5253
#if NET8_0_OR_GREATER
5354
public object GetKeyedService(Type serviceType, object serviceKey)
5455
{
55-
return _resolutionRoot.TryGet(serviceType, metadata => metadata.Get<ServiceKey>(nameof(ServiceKey))?.Key == serviceKey);
56+
var result = _resolutionRoot.TryGet(serviceType, metadata => DoesMetadataMatchServiceKey(serviceKey, metadata));
57+
return result;
5658
}
5759

5860
public object GetRequiredKeyedService(Type serviceType, object serviceKey)
5961
{
60-
throw new NotImplementedException();
62+
return _resolutionRoot.Get(serviceType, metadata => DoesMetadataMatchServiceKey(serviceKey, metadata));
63+
}
64+
65+
private static bool DoesMetadataMatchServiceKey(object serviceKey, IBindingMetadata metadata)
66+
{
67+
return metadata.Get<ServiceKey>(nameof(ServiceKey))?.Key == serviceKey;
6168
}
6269
#endif
6370
}

0 commit comments

Comments
 (0)