unitycontainer / microsoft-dependency-injection

Unity.Microsoft.DependencyInjection package
Apache License 2.0
63 stars 36 forks source link

Get Started Problem #38

Closed AndGa closed 5 years ago

AndGa commented 5 years ago
  1. Create .Net Core 2.2 Web App: dotnet new webapp
  2. Add NuGet Package: Install-Package Unity.Microsoft.DependencyInjection
  3. Customize Program: WebHost.CreateDefaultBuilder(args) .UseUnityServiceProvider() .UseStartup<Startup>();
  4. Customize Startup: services.AddMvc() .SetCompatibilityVersion(CompatibilityVersion.Version_2_2) .AddControllersAsServices();
  5. Run: dotnet run

I have got: Application startup exception: System.ArgumentNullException: Value cannot be null. Parameter name: source at System.Linq.Enumerable.Reverse[TSource](IEnumerable1 source) at Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication() crit: Microsoft.AspNetCore.Hosting.Internal.WebHost[6] Application startup exception System.ArgumentNullException: Value cannot be null. Parameter name: source at System.Linq.Enumerable.Reverse[TSource](IEnumerable1 source) at Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication()

Unhandled Exception: System.ArgumentNullException: Value cannot be null. Parameter name: source at System.Linq.Enumerable.Reverse[TSource](IEnumerable`1 source) at Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication() at Microsoft.AspNetCore.Hosting.Internal.WebHost.StartAsync(CancellationToken cancellationToken) at Microsoft.AspNetCore.Hosting.WebHostExtensions.RunAsync(IWebHost host, CancellationToken token, String shutdownMessage) at Microsoft.AspNetCore.Hosting.WebHostExtensions.RunAsync(IWebHost host, CancellationToken token) at Microsoft.AspNetCore.Hosting.WebHostExtensions.Run(IWebHost host) at _3.Program.Main(String[] args) in D:\TEMP\3\Program.cs:line 18

A similar problem is described here: https://github.com/unitycontainer/microsoft-dependency-injection/issues/17

What have i done wrong?

FYI: i have the problem with 5.9.2. (current release) but not with 5.9.0.

ENikS commented 5 years ago

Could you create a repo with code I could run and debug?

AndGa commented 5 years ago

here: GetStartedProblem.zip

H3xas commented 5 years ago

I have the faced the same issue.

When I have added .UseUnityServiceProvider(_container) to CreateWebHostBuilder method, I received exactly same exception.

I have tried to make a workaround for that adding to CreateWebHostBuilder method following code:

public static IWebHostBuilder CreateWebHostBuilder(string[] args)
{
    var webHost = WebHost.CreateDefaultBuilder(args)
        .UseUnityServiceProvider(BuildContainer())
        .UseStartup<Startup>();

    webHost.ConfigureServices(services =>
        {
            services.AddTransient<IEnumerable<IStartupFilter>>(p => new List<IStartupFilter>());
        });
    return webHost;
}

Where BuildContainer() method, just returns instance of IUnityContainer.

That solved the issue with StartupFilters being not resolved, however it lead to issue with app.UseMvc() in Startup.cs. Firstly, it reported that it cannot get services from: IEnumerable and if they were added in the same way as this "hack", it was notifying that it was empty.

ENikS commented 5 years ago

If I disable Unity and run it with built-in DI it is still crushing with the following error:

System.InvalidOperationException
  HResult=0x80131509
  Message=No service for type 'Microsoft.Extensions.DependencyInjection.IServiceProviderFactory`1[Unity.IUnityContainer]' has been registered.
  Source=Microsoft.Extensions.DependencyInjection.Abstractions
  StackTrace:
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType) in /_/src/DependencyInjection/DI.Abstractions/src/ServiceProviderServiceExtensions.cs:line 59
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider) in /_/src/DependencyInjection/DI.Abstractions/src/ServiceProviderServiceExtensions.cs:line 79
   at Microsoft.AspNetCore.Hosting.Internal.StartupLoader.ConfigureServicesDelegateBuilder`1.<>c__DisplayClass14_0.<ConfigureServices>g__ConfigureServicesWithContainerConfiguration|0(IServiceCollection services) in /_/src/Microsoft.AspNetCore.Hosting/Internal/StartupLoader.cs:line 137
   at Microsoft.AspNetCore.Hosting.ConventionBasedStartup.ConfigureServices(IServiceCollection services) in /_/src/Microsoft.AspNetCore.Hosting/Startup/ConventionBasedStartup.cs:line 43
   at Microsoft.AspNetCore.Hosting.Internal.WebHost.EnsureApplicationServices() in /_/src/Microsoft.AspNetCore.Hosting/Internal/WebHost.cs:line 180
   at Microsoft.AspNetCore.Hosting.Internal.WebHost.Initialize() in /_/src/Microsoft.AspNetCore.Hosting/Internal/WebHost.cs:line 110
   at Microsoft.AspNetCore.Hosting.WebHostBuilder.Build() in /_/src/Microsoft.AspNetCore.Hosting/WebHostBuilder.cs:line 187
   at _3.Program.Main(String[] args) in C:\Projects\GetStartedProblem\3\Program.cs:line 21

I have feeling it is not the Unity container you have a problem with. Am I missing something?

AndGa commented 5 years ago
  1. download and unzip my code example (with version 5.9.2)
  2. dotnet restore
  3. dotnet run
  4. you will get the error

And now test it with 5.9.0 or with 5.9.1:

  1. change version in 3.csproj <PackageReference Include="Unity.Microsoft.DependencyInjection" Version="5.9.1" />
  2. dotnet restore
  3. dotnet run
  4. with old version all work right

Conclusion: current version 5.9.2 is not OK. Please find/fix wrong changes. I suspect .UseUnityServiceProvider.

ENikS commented 5 years ago

I am getting the same error even if I do not use Unity at all.

In your test application disable Unity and make it use native Microsoft.Dependency.Injection It will throw the same exception.

Both, Unity and the Microsoft DI fail with exactly the same error. I think there is something wrong with the example itself.

Please verify and let me know.

AndGa commented 5 years ago

OK, forget my example, and make your own new "getting started" project with 5.9.2; i make it so:

  1. dotnet new webapp -n NewGettingStarted
  2. cd NewGettingStarted
  3. dotnet add package Unity.Microsoft.DependencyInjection
  4. dotnet restore
  5. dotnet run
  6. if you want you can test it now (without Unity) - all will work ok
  7. and now test your Unity.Microsoft.DependencyInjection 5.9.2: make changes from "Getting Started" page or just add .UseUnityServiceProvider - you will get error.
  8. remove .UseUnityServiceProvider - all will be repaired.

Just make your new web app with .net core 2.2 and your 5.9.2. as you can. Forget my example project. Make your own one. Your will see: problem appear only with 5.9.2

AndGa commented 5 years ago

I have found: the ConfigureServices must return not void but IServiceProvider:

services
.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
.AddControllersAsServices();
return services.BuildServiceProvider();

But ConfigureContainer will not be called !!!

AndGa commented 5 years ago

But in case:

var serviceProvider =
Unity.Microsoft.DependencyInjection.ServiceProvider.ConfigureServices(services)
as Unity.Microsoft.DependencyInjection.ServiceProvider;

ConfigureContainer((UnityContainer)serviceProvider);
return serviceProvider;

i get initial case: ConfigureContainer will be called but initial exception will be thrown.

:-(

if you try without ConfigureContainer - the same exception will be thrown:

var serviceProvider = Unity.Microsoft.DependencyInjection.ServiceProvider.ConfigureServices(services);
return serviceProvider;
ENikS commented 5 years ago

@AndGa It looks like Unity is failing to build RegistrPolicyResolver:

No public constructor is available for type Microsoft.Win32.RegistryKey.
_____________________________________________________
Exception occurred while:

·resolving type:  'RegistryKey'
  for parameter:  'policyRegKey'
  on constructor:  RegistryPolicyResolver(RegistryKey policyRegKey, IActivator activator)
   •resolving type:  'IRegistryPolicyResolver' mapped to 'RegistryPolicyResolver'
     for parameter:  'registryPolicyResolver'
     on constructor:  KeyManagementOptionsSetup(ILoggerFactory loggerFactory, IRegistryPolicyResolver registryPolicyResolver)
      •resolving type:  'IConfigureOptions`1' mapped to 'KeyManagementOptionsSetup'
       ·resolving type:  'IEnumerable`1'
         for parameter:  'setups'
         on constructor:  OptionsFactory`1(IEnumerable`1 setups, IEnumerable`1 postConfigures, IEnumerable`1 validations)
          •resolving type:  'IOptionsFactory`1' mapped to 'OptionsFactory`1'
            for parameter:  'factory'
            on constructor:  OptionsManager`1(IOptionsFactory`1 factory)
             •resolving type:  'IOptions`1' mapped to 'OptionsManager`1'
               for parameter:  'keyManagementOptions'
               on constructor:  XmlKeyManager(IOptions`1 keyManagementOptions, IActivator activator, ILoggerFactory loggerFactory)
                •resolving type:  'IKeyManager' mapped to 'XmlKeyManager'
                  for parameter:  'keyManager'
                  on constructor:  KeyRingProvider(IKeyManager keyManager, IOptions`1 keyManagementOptions, IDefaultKeyResolver defaultKeyResolver, ILoggerFactory loggerFactory)
                   •resolving type:  'IKeyRingProvider' mapped to 'KeyRingProvider'
                     for parameter:  'keyRingProvider'
                     on constructor:  DataProtectionStartupFilter(IKeyRingProvider keyRingProvider, ILoggerFactory loggerFactory)
                      •resolving type:  'IStartupFilter' mapped to 'DataProtectionStartupFilter'
                       ·resolving type:  'IEnumerable`1'