diff --git a/src/Autofac/Core/Activators/Reflection/ReflectionActivator.cs b/src/Autofac/Core/Activators/Reflection/ReflectionActivator.cs
index 84b3fc46d..3dd6f8467 100644
--- a/src/Autofac/Core/Activators/Reflection/ReflectionActivator.cs
+++ b/src/Autofac/Core/Activators/Reflection/ReflectionActivator.cs
@@ -290,12 +290,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.resx b/src/Autofac/Core/Activators/Reflection/ReflectionActivatorResources.resx
index 4cac50c7f..120f587f3 100644
--- a/src/Autofac/Core/Activators/Reflection/ReflectionActivatorResources.resx
+++ b/src/Autofac/Core/Activators/Reflection/ReflectionActivatorResources.resx
@@ -126,4 +126,9 @@
None of the constructors found with '{0}' on type '{1}' can be invoked with the available services and parameters:{2}
-
\ No newline at end of file
+
+ 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 for more info.
+
+
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
+
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
+
diff --git a/test/Autofac.Test/Core/Activators/Reflection/ReflectionActivatorTests.cs b/test/Autofac.Test/Core/Activators/Reflection/ReflectionActivatorTests.cs
index b4641e76d..42ebc72b2 100644
--- a/test/Autofac.Test/Core/Activators/Reflection/ReflectionActivatorTests.cs
+++ b/test/Autofac.Test/Core/Activators/Reflection/ReflectionActivatorTests.cs
@@ -1,6 +1,7 @@
// Copyright (c) Autofac Project. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
+using System.Reflection;
using Autofac.Core;
using Autofac.Core.Activators.Reflection;
using Autofac.Test.Scenarios.ConstructorSelection;
@@ -180,7 +181,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]
@@ -338,6 +339,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)
@@ -346,6 +361,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 9acd09277..b0d41257f 100644
--- a/test/Autofac.Test/Factory.cs
+++ b/test/Autofac.Test/Factory.cs
@@ -82,6 +82,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(