aspnet / DependencyInjection

[Archived] Contains common DI abstractions that ASP.NET Core and Entity Framework Core use. Project moved to https://github.com/aspnet/Extensions
Apache License 2.0
877 stars 320 forks source link

Generic Types Should Be Able to Be Depended and Injected by Implementation Factory #634

Closed IndreamLuo closed 6 years ago

IndreamLuo commented 6 years ago

https://github.com/aspnet/DependencyInjection/blob/4708d11dfe2a3df540578f026fc14d11a4f9ef48/src/DI/ServiceLookup/CallSiteFactory.cs#L36

Also refer to: https://github.com/aspnet/Home/issues/3036

Where:

if (implementationTypeInfo == null || !implementationTypeInfo.IsGenericTypeDefinition)
{
    throw new ArgumentException(
    Resources.FormatOpenGenericServiceRequiresOpenGenericImplementation(descriptor.ServiceType),
                            nameof(descriptors));
}

if (implementationTypeInfo.IsAbstract || implementationTypeInfo.IsInterface)
{
    throw new ArgumentException(Resources.FormatTypeCannotBeActivated(descriptor.ImplementationType, descriptor.ServiceType));
}

When there's generic type dependency with no concrete generic type injection but instance factory it'll throw the exception. Should be changed to like:

if ((implementationTypeInfo == null || !implementationTypeInfo.IsGenericTypeDefinition) **&& descriptor.ImplementationFactoryWithType == null**)
{
    throw new ArgumentException(
    Resources.FormatOpenGenericServiceRequiresOpenGenericImplementation(descriptor.ServiceType),
                            nameof(descriptors));
}
**else** if (implementationTypeInfo.IsAbstract || implementationTypeInfo.IsInterface)
{
throw new ArgumentException(
                            Resources.FormatTypeCannotBeActivated(descriptor.ImplementationType, descriptor.ServiceType));
}

In the case of using factory declaration of dependency as will be throwing exception "An unhandled exception of type 'System.ArgumentException' occurred in Microsoft.Extensions.DependencyInjection.dll: 'Open generic service type '[name of the type]' requires registering an open generic implementation type.'" in building web host which should be right in where new service descriptor is being added:

public class Startup
{
... ...
    public void ConfigureServices(IServiceCollection services)
    {
        ... ...
        services.Add[lifecycle type](myGenericType, provider => myFactory.GetInstance(myGenericType));
        ... ...
    }
}

And a new method should be provided as:

services.Add[lifecycle type](myGenericType, (provider, requiringType) => myFactory.GetInstance(requiringType));

And FactoryCallSite should be extended or new type of IServiceCallSite for factory with requiring type provided in invoking should be implemented.

aspnet-hello commented 6 years ago

This issue was moved to aspnet/Home#3037