dadhi / DryIoc

DryIoc is fast, small, full-featured IoC Container for .NET
MIT License
982 stars 122 forks source link

System.NullReferenceException: Object reference not set to an instance of an object #642

Open ericbrunner opened 1 month ago

ericbrunner commented 1 month ago

Hi,

We are facing such exception when calling containerResolver.Resolve<T>();

System.NullReferenceException: Object reference not set to an instance of an object. at DryIoc.Interpreter.TryInterpretAndUnwrapContainerException(IResolverContext r, Expression expr, Object& result) in //src/DryIoc/Container.cs:line 3073 at DryIoc.Container.ResolveAndCache(Int32 serviceTypeHash, Type serviceType, IfUnresolved ifUnresolved) in //src/DryIoc/Container.cs:line 441 at DryIoc.Container.DryIoc.IResolver.Resolve(Type serviceType, IfUnresolved ifUnresolved) in //src/DryIoc/Container.cs:line 392 at DryIoc.Resolver.Resolve[OvenDashboardItem](IResolver resolver, IfUnresolved ifUnresolved) in //src/DryIoc/Container.cs:line 8602

Its in a .NET MAUI App with target frameworks

<TargetFrameworks>net8.0;net8.0-android;net8.0-ios</TargetFrameworks>

and DryIoC.dll nuget version 5.4.3

We verified that e.g. the OvenDashboardItem and all it's injected dependencies in .ctor are properly registered in the container and the container is built without any error before we try to resolve that type. When we get that resolve exception we tried out to resolve all .ctor arguments from the container resolver with success and could manually create an instance with Activator.CreateInstance(typeof(OvenDashboardItem), arg1, arg2, ...).

The code section with containerResolver.Resolve<T>(); is invoked by several threads (race condition ?!). To mitigate that issue we tried a static lock around the containerResolver.Resolve<T>(); and it works. Now no exception is thrown. But that's just a workaround.

I'll try to create a tiny sample, but TBH I guess it will not we that easy.

Do you have any advice what we can further try out?

Thanks, Eric

dadhi commented 1 month ago

@ericbrunner Hi here,

Yes, the separated example/test is very much appreciated. It is hard to say about the reason without more details, and it is a shame that .NET still does not have an option to expose the Null reference target.

Meanwhile I would suggest to try out the DryIoc v6.0.0-preview-07. There are many fixes and changes that may solved the problem already.

ericbrunner commented 1 month ago

@ericbrunner Hi here,

Yes, the separated example/test is very much appreciated. It is hard to say about the reason without more details, and it is a shame that .NET still does not have an option to expose the Null reference target.

Meanwhile I would suggest to try out the DryIoc v6.0.0-preview-07. There are many fixes and changes that may solved the problem already.

thank you very much for your kind reply @dadhi :-) We will try the DryIoc v6.0.0-preview-07 and I try to create a Reproduction Sample.

ericbrunner commented 1 month ago

Hi @dadhi I tried to mimic our situation in a test: https://github.com/ericbrunner/DryIoCResolverExploration/blob/6dc9478bd20c22a6cb22dfebd0f3a3991da8ddf5/DryIoCResolverExploration/TestProject/UnitTest1.cs#L41

Sadly, I could not reproduce the exception I get at line: https://github.com/ericbrunner/DryIoCResolverExploration/blob/6dc9478bd20c22a6cb22dfebd0f3a3991da8ddf5/DryIoCResolverExploration/DashboardConnectors.Library/Connectors/Base/ApplianceModelDashboardConnector.cs#L26

Full Project is here: https://github.com/ericbrunner/DryIoCResolverExploration/tree/main

I'll try some further tests to reproduce our situation but I allready informed the colleague to update to what you suggested.

ericbrunner commented 1 month ago

@ericbrunner Hi here,

Yes, the separated example/test is very much appreciated. It is hard to say about the reason without more details, and it is a shame that .NET still does not have an option to expose the Null reference target.

Meanwhile I would suggest to try out the DryIoc v6.0.0-preview-07. There are many fixes and changes that may solved the problem already.

Colleague of mine tested with suggested version v6.0.0-preview-07 and now gets a different exception:

System.MissingMethodException: Could not find InternalPreserveStackTrace at DryIoc.ReflectionTools.TryRethrowWithPreservedStackTrace(Exception ex) in /Users/warborg/.nuget/packages/dryioc/6.0.0-preview-07/contentFiles/cs/netstandard2.0/DryIoc/Container.cs:line 15728 at DryIoc.Interpreter.TryInterpretAndUnwrapContainerException(IResolverContext r, Expression expr, Object& result) in /Users/warborg/.nuget/packages/dryioc/6.0.0-preview-07/contentFiles/cs/netstandard2.0/DryIoc/Container.cs:line 3265 at DryIoc.Container.ResolveAndCache(Int32 serviceTypeHash, Type serviceType, IfUnresolved ifUnresolved) in /Users/warborg/.nuget/packages/dryioc/6.0.0-preview-07/contentFiles/cs/netstandard2.0/DryIoc/Container.cs:line 417 at DryIoc.Container.Resolve(Type serviceType, IfUnresolved ifUnresolved) in /Users/warborg/.nuget/packages/dryioc/6.0.0-preview-07/contentFiles/cs/netstandard2.0/DryIoc/Container.cs:line 369 at Miele.Libraries.Foundation.Modules.DependencyInjection.Implementation.DryIocContainer.Resolve[OvenDashboardItem]() in /Users/warborg/Projects/01 Miele/Foundation Library/src/Modules/DependencyInjection/Implementation/DryIocContainer.cs:line 17 at Miele.Modules.Domestic.Public.Dashboard.DashboardConnector.ApplianceModelDashboardConnector`2[[Miele.Modules.Oven.ApplianceCommunication.Contract.ApplianceModelInterfaces.IOvenDashboardItemModel, Miele.Modules.Oven.ApplianceCommunication.Contract, Version=9.0.10.0, Culture=neutral, PublicKeyToken=null],[Miele.Modules.Oven.UI.Dashboard.OvenDashboardItem, Miele.Modules.Oven.UI, Version=9.0.10.0, Culture=neutral, PublicKeyToken=null]].CreateDashboardItem(MetaAppliance metaAppliance) in /Users/warborg/Projects/01 Miele/Foundation Library/Sandbox.Modules/src/Domestic.Public/Dashboard/DashboardConnector/ApplianceModelDashboardConnector.cs:line 58

for some reason it's using the netstandard2.0 version and probably trying to use something from .net8

dadhi commented 1 month ago

Nice. Thanks for the testing. I will fix it and return back with the new version to try.