From 020f5e94bf62dbafa4fa7c183f28ab8af47489f4 Mon Sep 17 00:00:00 2001 From: Alistair Evans Date: Sun, 11 Jul 2021 14:39:32 +0100 Subject: [PATCH 1/5] Add links in no constructors bindable message, and show simpler message if we're using the default binder --- .../Reflection/ReflectionActivator.cs | 24 ++++++++++++++----- .../ReflectionActivatorResources.Designer.cs | 15 +++++++++++- .../ReflectionActivatorResources.resx | 11 +++++++-- 3 files changed, 41 insertions(+), 9 deletions(-) diff --git a/src/Autofac/Core/Activators/Reflection/ReflectionActivator.cs b/src/Autofac/Core/Activators/Reflection/ReflectionActivator.cs index 4d05b78e7..d0cbb06d5 100644 --- a/src/Autofac/Core/Activators/Reflection/ReflectionActivator.cs +++ b/src/Autofac/Core/Activators/Reflection/ReflectionActivator.cs @@ -201,12 +201,24 @@ private string GetBindingFailureMessage(BoundConstructor[] constructorBindings) reasons.Append(invalid.Description); } - return string.Format( - CultureInfo.CurrentCulture, - ReflectionActivatorResources.NoConstructorsBindable, - ConstructorFinder, - _implementationType, - reasons); + if (ConstructorFinder is DefaultConstructorFinder) + { + // Simplify the text for the common default finder case (to make the message easier to understand). + return string.Format( + CultureInfo.CurrentCulture, + ReflectionActivatorResources.NoConstructorsBindableDefaultBinder, + _implementationType, + reasons); + } + else + { + return string.Format( + CultureInfo.CurrentCulture, + ReflectionActivatorResources.NoConstructorsBindable, + ConstructorFinder, + _implementationType, + reasons); + } } private void InjectProperties(object instance, IComponentContext context) diff --git a/src/Autofac/Core/Activators/Reflection/ReflectionActivatorResources.Designer.cs b/src/Autofac/Core/Activators/Reflection/ReflectionActivatorResources.Designer.cs index 928433cc1..f66f05437 100644 --- a/src/Autofac/Core/Activators/Reflection/ReflectionActivatorResources.Designer.cs +++ b/src/Autofac/Core/Activators/Reflection/ReflectionActivatorResources.Designer.cs @@ -79,12 +79,25 @@ internal static string NoConstructorsAvailable { } /// - /// Looks up a localized string similar to None of the constructors found with '{0}' on type '{1}' can be invoked with the available services and parameters:{2}. + /// Looks up a localized string similar to None of the constructors found with '{0}' on type '{1}' can be invoked with the available services and parameters:{2} + /// + ///See https://autofac.rtfd.io/help/no-constructors-bindable for more info.. /// internal static string NoConstructorsBindable { get { return ResourceManager.GetString("NoConstructorsBindable", resourceCulture); } } + + /// + /// Looks up a localized string similar to None of the constructors found on type '{0}' can be invoked with the available services and parameters:{1} + /// + ///See https://autofac.rtfd.io/help/no-constructors-bindable-default-binder for more info.. + /// + internal static string NoConstructorsBindableDefaultBinder { + get { + return ResourceManager.GetString("NoConstructorsBindableDefaultBinder", resourceCulture); + } + } } } diff --git a/src/Autofac/Core/Activators/Reflection/ReflectionActivatorResources.resx b/src/Autofac/Core/Activators/Reflection/ReflectionActivatorResources.resx index 4cac50c7f..32d70573c 100644 --- a/src/Autofac/Core/Activators/Reflection/ReflectionActivatorResources.resx +++ b/src/Autofac/Core/Activators/Reflection/ReflectionActivatorResources.resx @@ -124,6 +124,13 @@ No constructors on type '{0}' can be found with the constructor finder '{1}'. - None of the constructors found with '{0}' on type '{1}' can be invoked with the available services and parameters:{2} + None of the constructors found with '{0}' on type '{1}' can be invoked with the available services and parameters:{2} + +See https://autofac.rtfd.io/help/no-constructors-bindable for more info. + + + None of the constructors found on type '{0}' can be invoked with the available services and parameters:{1} + +See https://autofac.rtfd.io/help/no-constructors-bindable-default-binder for more info. - \ No newline at end of file + From 6197a514d24a6c7e28e9c00acbe4c1b96b9bdbe5 Mon Sep 17 00:00:00 2001 From: Alistair Evans Date: Sun, 11 Jul 2021 14:57:39 +0100 Subject: [PATCH 2/5] Take the link out for the non-default-binder case. --- .../Reflection/ReflectionActivatorResources.Designer.cs | 6 ++---- .../Activators/Reflection/ReflectionActivatorResources.resx | 6 ++---- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/Autofac/Core/Activators/Reflection/ReflectionActivatorResources.Designer.cs b/src/Autofac/Core/Activators/Reflection/ReflectionActivatorResources.Designer.cs index f66f05437..950e10673 100644 --- a/src/Autofac/Core/Activators/Reflection/ReflectionActivatorResources.Designer.cs +++ b/src/Autofac/Core/Activators/Reflection/ReflectionActivatorResources.Designer.cs @@ -79,9 +79,7 @@ internal static string NoConstructorsAvailable { } /// - /// Looks up a localized string similar to None of the constructors found with '{0}' on type '{1}' can be invoked with the available services and parameters:{2} - /// - ///See https://autofac.rtfd.io/help/no-constructors-bindable for more info.. + /// Looks up a localized string similar to None of the constructors found with '{0}' on type '{1}' can be invoked with the available services and parameters:{2}. /// internal static string NoConstructorsBindable { get { @@ -92,7 +90,7 @@ internal static string NoConstructorsBindable { /// /// Looks up a localized string similar to None of the constructors found on type '{0}' can be invoked with the available services and parameters:{1} /// - ///See https://autofac.rtfd.io/help/no-constructors-bindable-default-binder for more info.. + ///See https://autofac.rtfd.io/help/no-constructors-bindable for more info.. /// internal static string NoConstructorsBindableDefaultBinder { get { diff --git a/src/Autofac/Core/Activators/Reflection/ReflectionActivatorResources.resx b/src/Autofac/Core/Activators/Reflection/ReflectionActivatorResources.resx index 32d70573c..120f587f3 100644 --- a/src/Autofac/Core/Activators/Reflection/ReflectionActivatorResources.resx +++ b/src/Autofac/Core/Activators/Reflection/ReflectionActivatorResources.resx @@ -124,13 +124,11 @@ No constructors on type '{0}' can be found with the constructor finder '{1}'. - None of the constructors found with '{0}' on type '{1}' can be invoked with the available services and parameters:{2} - -See https://autofac.rtfd.io/help/no-constructors-bindable for more info. + None of the constructors found with '{0}' on type '{1}' can be invoked with the available services and parameters:{2} None of the constructors found on type '{0}' can be invoked with the available services and parameters:{1} -See https://autofac.rtfd.io/help/no-constructors-bindable-default-binder for more info. +See https://autofac.rtfd.io/help/no-constructors-bindable for more info. From f248640bb57015a0cd96e72b84ef672674cb694d Mon Sep 17 00:00:00 2001 From: Alistair Evans Date: Tue, 13 Jul 2021 06:39:12 +0100 Subject: [PATCH 3/5] Fix test (and add another one for the custom binder check) --- .../Reflection/ReflectionActivatorTests.cs | 22 ++++++++++++++++++- test/Autofac.Test/Factory.cs | 10 +++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/test/Autofac.Test/Core/Activators/Reflection/ReflectionActivatorTests.cs b/test/Autofac.Test/Core/Activators/Reflection/ReflectionActivatorTests.cs index 25bfae9ae..8a09e255f 100644 --- a/test/Autofac.Test/Core/Activators/Reflection/ReflectionActivatorTests.cs +++ b/test/Autofac.Test/Core/Activators/Reflection/ReflectionActivatorTests.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; +using System.Reflection; using Autofac.Core; using Autofac.Core.Activators.Reflection; using Autofac.Test.Scenarios.ConstructorSelection; @@ -185,7 +186,7 @@ public void NonPublicConstructorsIgnored() var dx = Assert.Throws(() => invoker(Factory.CreateEmptyContainer(), Factory.NoParameters)); - Assert.Contains(typeof(DefaultConstructorFinder).Name, dx.Message); + Assert.Contains(typeof(InternalDefaultConstructor).Name, dx.Message); } [Fact] @@ -343,6 +344,20 @@ public void ConstructorSelectorCannotReturnInvalidBinding() Assert.Throws(() => invoker(container, Factory.NoParameters)); } + [Fact] + public void CustomBinderNameIncludedInErrorMessage() + { + var target = Factory.CreateReflectionActivator(typeof(InternalDefaultConstructor), new SimpleConstructorFinder()); + + // Constructor finding happens at pipeline construction; not when the pipeline is invoked. + var invoker = target.GetPipelineInvoker(Factory.CreateEmptyComponentRegistry()); + + var dx = Assert.Throws(() => + invoker(Factory.CreateEmptyContainer(), Factory.NoParameters)); + + Assert.Contains(typeof(SimpleConstructorFinder).Name, dx.Message); + } + private class MisbehavingConstructorSelector : IConstructorSelector { public BoundConstructor SelectConstructorBinding(BoundConstructor[] constructorBindings, IEnumerable parameters) @@ -351,6 +366,11 @@ public BoundConstructor SelectConstructorBinding(BoundConstructor[] constructorB } } + private class SimpleConstructorFinder : IConstructorFinder + { + public ConstructorInfo[] FindConstructors(Type targetType) => targetType.GetDeclaredPublicConstructors(); + } + public class AcceptsIntParameter { public AcceptsIntParameter(int i) diff --git a/test/Autofac.Test/Factory.cs b/test/Autofac.Test/Factory.cs index c836a0a0f..bad4d70b1 100644 --- a/test/Autofac.Test/Factory.cs +++ b/test/Autofac.Test/Factory.cs @@ -85,6 +85,16 @@ public static ReflectionActivator CreateReflectionActivator(Type implementation, properties); } + public static ReflectionActivator CreateReflectionActivator(Type implementation, IConstructorFinder customFinder) + { + return new ReflectionActivator( + implementation, + customFinder, + new MostParametersConstructorSelector(), + NoParameters, + NoProperties); + } + public static ReflectionActivator CreateReflectionActivator(Type implementation, IConstructorSelector customSelector) { return new ReflectionActivator( From db84bb642cc273be603363ceefa154419a49e6cf Mon Sep 17 00:00:00 2001 From: Travis Illig Date: Wed, 7 Dec 2022 09:36:02 -0800 Subject: [PATCH 4/5] Doc link for service not registered. --- ...ponentNotRegisteredExceptionResources.resx | 60 ++++++++++--------- 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/src/Autofac/Core/Registration/ComponentNotRegisteredExceptionResources.resx b/src/Autofac/Core/Registration/ComponentNotRegisteredExceptionResources.resx index 903522356..41cbf4ee7 100644 --- a/src/Autofac/Core/Registration/ComponentNotRegisteredExceptionResources.resx +++ b/src/Autofac/Core/Registration/ComponentNotRegisteredExceptionResources.resx @@ -1,17 +1,17 @@  - @@ -118,6 +118,8 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - The requested service '{0}' has not been registered. To avoid this exception, either register a component to provide the service, check for service registration using IsRegistered(), or use the ResolveOptional() method to resolve an optional dependency. + The requested service '{0}' has not been registered. To avoid this exception, either register a component to provide the service, check for service registration using IsRegistered(), or use the ResolveOptional() method to resolve an optional dependency. + +See https://autofac.rtfd.io/help/service-not-registered for more info. - \ No newline at end of file + From 0faf5c82680eafdfc97315e04695e869ac9433c9 Mon Sep 17 00:00:00 2001 From: Travis Illig Date: Wed, 7 Dec 2022 10:05:32 -0800 Subject: [PATCH 5/5] InstancePerMatchingLifetimeScope doc link. --- .../MatchingScopeLifetimeResources.resx | 60 ++++++++++--------- 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/src/Autofac/Core/Lifetime/MatchingScopeLifetimeResources.resx b/src/Autofac/Core/Lifetime/MatchingScopeLifetimeResources.resx index 31503a186..9a09571fa 100644 --- a/src/Autofac/Core/Lifetime/MatchingScopeLifetimeResources.resx +++ b/src/Autofac/Core/Lifetime/MatchingScopeLifetimeResources.resx @@ -1,17 +1,17 @@  - @@ -120,6 +120,8 @@ No scope with a tag matching '{0}' is visible from the scope in which the instance was requested. -If you see this during execution of a web application, it generally indicates that a component registered as per-HTTP request is being requested by a SingleInstance() component (or a similar scenario). Under the web integration always request dependencies from the dependency resolver or the request lifetime scope, never from the container itself. +If you see this during execution of a web application, it generally indicates that a component registered as per-HTTP request is being requested by a SingleInstance() component (or a similar scenario). Under the web integration always request dependencies from the dependency resolver or the request lifetime scope, never from the container itself. + +See https://autofac.rtfd.io/help/no-matching-scope for more info. - \ No newline at end of file +