ssannandeji / Zenject-2019

Dependency Injection Framework for Unity3D
MIT License
2.53k stars 366 forks source link

Error while finalizing previous binding! Contract: XXXX Identifier: NULL When Multi Threading #637

Open dishanphilips opened 5 years ago

dishanphilips commented 5 years ago

Hello,

We are using Zenject within a .Net core project. If there are multiple threads that are trying to resolve the initial bindings, then the error occurs.

Stack:

1560368986483 Error [Controller] OnActionExecuting Stack : at Zenject.ProviderBindingFinalizer.FinalizeBinding(DiContainer container) in Zenject\Source\Binding\Finalizers\ProviderBindingFinalizer.cs:line 41 at Zenject.BindStatement.FinalizeBinding(DiContainer container) in Zenject\Source\Binding\BindInfo\BindStatement.cs:line 68 at Zenject.DiContainer.FinalizeBinding(BindStatement binding) in Zenject\Source\Main\DiContainer.cs:line 1961 at Zenject.DiContainer.FlushBindings() in Zenject\Source\Main\DiContainer.cs:line 1941 at Zenject.DiContainer.StartBinding(Boolean flush) in Zenject\Source\Main\DiContainer.cs:line 1977 at Zenject.DiContainer.BindInterfacesAndSelfTo(Type type) in Zenject\Source\Main\DiContainer.cs:line 2141 at Zenject.DiContainer.BindInterfacesAndSelfTo[T]() in Zenject\Source\Main\DiContainer.cs:line 2136

The issue is that the following dictionaries are being modified without a lock.

static readonly Dictionary<Type, bool> _isClosedGenericType = new Dictionary<Type, bool>(); static readonly Dictionary<Type, bool> _isOpenGenericType = new Dictionary<Type, bool>(); static readonly Dictionary<Type, bool> _isValueType = new Dictionary<Type, bool>(); static readonly Dictionary<Type, Type[]> _interfaces = new Dictionary<Type, Type[]>();

We were able to fix this by doing :

lock (_isOpenGenericType) { if (!_isOpenGenericType.TryGetValue(type, out result)) { result = type.IsGenericType() && type == type.GetGenericTypeDefinition(); _isOpenGenericType[type] = result; } }