-
-
Notifications
You must be signed in to change notification settings - Fork 122
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
Support Keyed Services in DryIoc.MS.DI for the Microsoft.Extensions.DependencyInjection V8 #587
Comments
Let's address a challenge of the not-uniqueness of the MS.DI keyed services comparing to the uniqueness of DryIoc keyed services. Solution 1Create the composite key for the second, third, etc. MS key adding its index into the pair, e.g. "foo", ("foo", 1), ("foo", 2). Pros:
Cons:
Solution 2Represent the MS keys as DryIoc metadata Pros:
Cons:
|
Problems to solveThe multiple same key registrationsDryIoc treats the service key as unique ID for the same service type. So it prevents you with registering the same service type with the same service key. ServiceDecriptor.KeyedImplementationFactory has the key parameterThe type of Problem is that DryIoc does not supply a service key into the KeyedService.AnyKeyWe need to support the So far, so good. But what is this thing? See the next section for the reveal :-P [Fact]
public void ResolveKeyedServiceSingletonFactoryWithAnyKeyIgnoreWrongType()
{
var serviceCollection = new ServiceCollection();
serviceCollection.AddKeyedTransient<IService, ServiceWithIntKey>(KeyedService.AnyKey);
var provider = CreateServiceProvider(serviceCollection);
Assert.Null(provider.GetService<IService>());
Assert.NotNull(provider.GetKeyedService<IService>(87));
Assert.ThrowsAny<InvalidOperationException>(() => provider.GetKeyedService<IService>(new object()));
} ServiceKeyAttributeMarks the parameter to be injected with the resolution service key as in the following case used by the test above: internal class ServiceWithIntKey : IService
{
private readonly int _id;
public ServiceWithIntKey([ServiceKey] int id) => _id = id;
} Moreover, we need to select the appropriate constructor in presence of attributeIn the example internal class Service : IService
{
private readonly string _id;
public Service() => _id = Guid.NewGuid().ToString();
public Service([ServiceKey] string id) => _id = id;
public override string? ToString() => _id;
} FromKeyedServicesAttribute internal class OtherService
{
public OtherService(
[FromKeyedServices("service1")] IService service1,
[FromKeyedServices("service2")] IService service2)
{
Service1 = service1;
Service2 = service2;
}
public IService Service1 { get; }
public IService Service2 { get; }
} |
Seems like we are doing the same Key for the same service Type in DryIoc.MefAttributedModel. Question, can we use the MEF for MS.DI?... Btw, how to get all non-keyed services in the collection? //cc @yallie |
Ok, for the last 2 failing tests we need the #618 |
@dadhi, sorry, I'm on vacation, have no PC to look into it. Will return next Monday. |
@yallie Enjoy vacation, I have moved the thing already and optimized it along the way. |
done |
You probably have it on your radar, but if not then here is a reminder to look into expanding the support for using DryIoc as the container in applications using the Microsoft.Extensions.Hosting framework.
When .NET 8 is released, and the Microsoft.Extensions.Hosting package version 8 is released, Microsoft has finally added keyed service support. The bridge between DryIoc and IServiceCollection need to be added so that these can be used also when DryIoc is the underlying container.
The following example runs with the new hosting nuget package, but uncomment the DryIoc configuration and it throws an InvalidOperationException with the message
This service descriptor is keyed. Your service provider may not support keyed services.
.interface and classes for complete code
The text was updated successfully, but these errors were encountered: