Scrutor icon indicating copy to clipboard operation
Scrutor copied to clipboard

"Value cannot be null" ArgumentNullException on .Net Framework 4.8

Open dcuccia opened this issue 6 years ago • 14 comments

Hi! I'm running into an issue with Scrutor 3.1 when multitargeting .Net 4.8 and .Net Core 3.0. The offending code is occurring in a .Net Standard 2.0 library:

var collection = new ServiceCollection()
    .Scan(scan =>
        scan.FromApplicationDependencies()
            .AddClasses(classes => classes.AssignableTo<IMyInterface>())
            .AsSelfWithInterfaces()
            .WithTransientLifetime()
        );

This code works fine for the .Net Core 3.0 runtime, but fails on 4.8 with a "Value cannot be null" ArgumentNullException. Are there possibly additional explicit Scrutor dependencies I need to add for .Net Framework 4.8?

The source for this project is here. The multitargeted test project contains the following:

<PropertyGroup>
    <TargetFrameworks>netcoreapp3.0;net48</TargetFrameworks>
</PropertyGroup>

the exception details with partial stack trace are below:

System.ArgumentNullException HResult=0x80004003 Message=Value cannot be null. Parameter name: assembly Source=Scrutor StackTrace: at Scrutor.Preconditions.NotNull[T](T value, String parameterName) at Scrutor.TypeSourceSelector.FromAssemblyDependencies(Assembly assembly) at Scrutor.TypeSourceSelector.FromApplicationDependencies(Func2 predicate) at Scrutor.TypeSourceSelector.FromApplicationDependencies() at Vts.MonteCarlo.DetectorInputProvider.<>c.<get_ServiceProvider>b__2_0(ITypeSourceSelector scan) in C:\Projects\dcuccia-vts\src\Vts\MonteCarlo\DataStructures\DetectorInputProvider.cs:line 23 at Microsoft.Extensions.DependencyInjection.ServiceCollectionExtensions.Scan(IServiceCollection services, Action1 action)

I'm quite new to this tool, so it's likely I'm just not setting things up properly. Let me know if there's more information I can provide to help resolve.

Thanks! David

dcuccia avatar Nov 24 '19 21:11 dcuccia

Following up on this. I cloned Scrutor and added the .csproj to my project directly.

It seems that both 'try' and 'catch' paths are failing in TypeSourceSelector.FromApplicationDependencies:

  1. DependencyContext.Default from Microsoft.Extensions.DependencyModel is null
  2. Assembly.GetEntryAssembly() is returning null

Feels like there is some .Net Framework bootstrapping I might be missing...

dcuccia avatar Nov 24 '19 22:11 dcuccia

Hi @dcuccia! 👋

Thanks for filing this issue. Can you try adding <PreserveCompilationContext>true</PreserveCompilationContext> to a PropertyGroup in your project file and see if it makes a difference? 🤔

khellang avatar Nov 25 '19 07:11 khellang

No problem, thanks for your reply. Tried that line in either the Scrutor-containing netstandard2.0 library, or the netcoreapp3.0 consuming library, or both with no luck - same issue.

dcuccia avatar Nov 26 '19 03:11 dcuccia

Hi @khellang, any thoughts on how I might debug this further?

dcuccia avatar Dec 04 '19 21:12 dcuccia

Not really, I've never seen Assembly.GetEntryAssembly() return null before. I mean; how can you even run an assembly without an entrypoint? 🤔

khellang avatar Dec 04 '19 22:12 khellang

I can also confirm I get a nullreference exception in FromApplicationDependencies

304NotModified avatar Dec 05 '19 21:12 304NotModified

NullReferenceException? 🤔

khellang avatar Dec 05 '19 22:12 khellang

I will recheck and add the full stacktrace for the error :angel:

304NotModified avatar Dec 05 '19 22:12 304NotModified

Confirming I'm still seeing this on 3.2

dcuccia avatar Feb 25 '20 23:02 dcuccia

There hasn't been any attempts at fixing this as I have no clue how to reproduce it. I'm afraid I have to require more information or even better; a pull request to fix this 😞

khellang avatar Feb 25 '20 23:02 khellang

@khellang understood, thanks. I will try at least to repro.

dcuccia avatar Feb 25 '20 23:02 dcuccia

@khellang I can now reproduce the error in isolation. See my repro code here:

https://github.com/dcuccia/ScrutorArgumentNullExceptionDemo

(currently requires a parallel checked-out Scrutor source tree for easy debugging)

What was driving me nuts is that I was unable to reproduce with a command-line exe, thinking maybe there was something to do with the complexity of my original project. Then, I added a simple unit test and BANG - you can see that the test passes with netcoreapp3.0, but fails with net48. Maybe related to this issue:

https://github.com/dotnet/sdk/issues/5654

I'll keep digging to see if there's a simple work-around, but if you have time let me know what you think.

Thanks!

dcuccia avatar Feb 29 '20 21:02 dcuccia

See also: https://github.com/dotnet/sdk/issues/6239

Seems like it's related to an assembly name equality check. Setting <PreserveCompilationContext>true</PreserveCompilationContext> doesn't seem to fix it for me.

dcuccia avatar Feb 29 '20 21:02 dcuccia

Didn't say this explicitly, but it appears that this is only an issue when running inside other tooling, e.g. Resharper or VS Test environments (and only for net48).

dcuccia avatar Feb 29 '20 21:02 dcuccia