ipjohnson / Grace

Grace is a feature rich dependency injection container library
MIT License
336 stars 33 forks source link

BUG TryLocate<T> throw exception and (Try)Locate failed #134

Closed mcdis closed 6 years ago

mcdis commented 6 years ago

Code:

private IUiMenuSettingsItemEditor CreateEditor(UiMenuItemScheme _scheme)
      {
         var child = p_shell.Container.CreateChildScope();
         child.Configure(_ =>
         {
            _.ExportInstance<IUiMenuSettingsJsonSettingProvider>(
               new UiMenuSettingsJsonSettingProvider(_scheme.Settings));
         });
         // EXCEPTION HERE  \/
         if (child.TryLocate<IUiMenuSettingsItemEditor>(out var editor, withKey: _scheme.Id))
            return editor;
         child.Dispose();
         return null;
      }

where:

   class UiMenuItemContainerEditor : IUiMenuSettingsItemEditor, IUiMenuEditorItemContainer
   {
      // _shell resolved - OK, but _settings failed
      public UiMenuItemContainerEditor(IUiShell _shell,
           IUiMenuSettingsJsonSettingProvider _settings)
      {         
          // ...
      }
   }

child container configuration behaviors:

Message

Grace.DependencyInjection.Exceptions.LocateException: 'Dynamic constructor could not find the following parameters IUiMenuSettingsJsonSettingProvider _settings
1 Importing MCDis.App.Shell.Ui.Interface.MenuSettingsEditor.IUiMenuSettingsItemEditor 

StackTrace:

   в lambda_method(Closure , IExportLocatorScope , IDisposalScope , IInjectionContext )
   в lambda_method(Closure , IExportLocatorScope , IDisposalScope , IInjectionContext )
   в Grace.DependencyInjection.Lifestyle.SingletonLifestyle.ProvideLifestyleExpression(IInjectionScope scope, IActivationExpressionRequest request, Func`2 activationExpression)
   в Grace.DependencyInjection.Impl.Expressions.DefaultStrategyExpressionBuilder.GetActivationExpression(IInjectionScope scope, IActivationExpressionRequest request, TypeActivationConfiguration activationConfiguration, ICompiledLifestyle lifestyle)
   в Grace.DependencyInjection.Impl.CompiledStrategies.CompiledExportStrategy.GetActivationExpression(IInjectionScope scope, IActivationExpressionRequest request)
   в Grace.DependencyInjection.Impl.CompiledStrategies.CompiledExportStrategy.GetActivationStrategyDelegate(IInjectionScope scope, IActivationStrategyCompiler compiler, Type activationType)
   в Grace.DependencyInjection.Impl.ActivationStrategyCompiler.FindKeyedDelegate(IInjectionScope scope, Type locateType, ActivationStrategyFilter consider, Object key)
   в Grace.DependencyInjection.Impl.ActivationStrategyCompiler.LocateStrategyFromCollectionContainers(IInjectionScope scope, Type locateType, ActivationStrategyFilter consider, Object key, IInjectionContext injectionContext)
   в Grace.DependencyInjection.Impl.ActivationStrategyCompiler.FindDelegate(IInjectionScope scope, Type locateType, ActivationStrategyFilter consider, Object key, IInjectionContext injectionContext, Boolean checkMissing)
   в Grace.DependencyInjection.Impl.InjectionScope.InternalLocate(IExportLocatorScope scope, IDisposalScope disposalScope, Type type, ActivationStrategyFilter consider, Object key, IInjectionContext injectionContext, Boolean allowNull, Boolean isDynamic)
   в Grace.DependencyInjection.Impl.InjectionScope.Grace.DependencyInjection.IInjectionScope.LocateFromChildScope(IExportLocatorScope childScope, IDisposalScope disposalScope, Type type, Object extraData, ActivationStrategyFilter consider, Object key, Boolean allowNull, Boolean isDynamic)
   в Grace.DependencyInjection.Impl.InjectionScope.InternalLocate(IExportLocatorScope scope, IDisposalScope disposalScope, Type type, ActivationStrategyFilter consider, Object key, IInjectionContext injectionContext, Boolean allowNull, Boolean isDynamic)
   в Grace.DependencyInjection.Impl.InjectionScope.TryLocate[T](T& value, Object extraData, ActivationStrategyFilter consider, Object withKey, Boolean isDynamic)

if I remove IUiMenuSettingsJsonSettingProvider _settings from constructor of UiMenuItemContainerEditor all works,

mcdis commented 6 years ago

SOLVED becouse wrong IUiMenuSettingsItemEditor registration, but the question is still open why TryLocate throw exception

ipjohnson commented 6 years ago

@mcdis I'm not sure I follow the example. Are you expecting the container to catch the exception or are you expecting the container not to throw an exception when a child dependency is missing on an export that is found?

mcdis commented 6 years ago

I've wrong lifecycle configuration in root container for some type. I used singleton instead per request, but TryLocate instead return false throw exception in child container. If I understood right TryLocate by design have not to throw exception but sometimes it throw, See Nessage and stacktrace.

ipjohnson commented 6 years ago

@mcdis the intention of TryLocate is to attempt to locate an export that matches the requested type. It does not walk it's way down the dependency graph testing to see if children can be resolved. What you are describing would be far to costly performance wise also from my stand point it just masks the real problem in the container configuration.

I do not envision Grace changing for this use case.