diff --git a/src/Autofac/RegistrationExtensions.cs b/src/Autofac/RegistrationExtensions.cs
index 85eeb046f..c0b1a64b4 100644
--- a/src/Autofac/RegistrationExtensions.cs
+++ b/src/Autofac/RegistrationExtensions.cs
@@ -882,6 +882,35 @@ private static Type[] GetImplementedInterfaces(Type type)
return registration.WithProperty(new NamedPropertyParameter(propertyName, propertyValue));
}
+ ///
+ /// Configure an explicit value for a property.
+ ///
+ /// Registration limit type.
+ /// Activator data type.
+ /// Registration style.
+ /// Type of the property being assigned.
+ /// Registration to set property on.
+ /// Expression of a property on the target type.
+ /// Value to supply to the property.
+ /// A registration builder allowing further configuration of the component.
+ public static IRegistrationBuilder
+ WithProperty(
+ this IRegistrationBuilder registration,
+ Expression> propertyExpression,
+ TProperty propertyValue)
+ where TReflectionActivatorData : ReflectionActivatorData
+ {
+ if (registration == null) throw new ArgumentNullException(nameof(registration));
+ if (propertyExpression == null) throw new ArgumentNullException(nameof(propertyExpression));
+ if (propertyValue == null) throw new ArgumentNullException(nameof(propertyValue));
+
+ var propertyInfo = (propertyExpression.Body as MemberExpression)?.Member as PropertyInfo;
+ if (propertyInfo == null)
+ throw new ArgumentOutOfRangeException(nameof(propertyExpression), RegistrationExtensionsResources.ExpressionDoesNotReferToProperty);
+
+ return registration.WithProperty(new NamedPropertyParameter(propertyInfo.Name, propertyValue));
+ }
+
///
/// Configure an explicit value for a property.
///
diff --git a/src/Autofac/RegistrationExtensionsResources.Designer.cs b/src/Autofac/RegistrationExtensionsResources.Designer.cs
index a71f7ffc9..1b0cd5b59 100644
--- a/src/Autofac/RegistrationExtensionsResources.Designer.cs
+++ b/src/Autofac/RegistrationExtensionsResources.Designer.cs
@@ -10,7 +10,6 @@
namespace Autofac {
using System;
- using System.Reflection;
///
@@ -20,7 +19,7 @@ namespace Autofac {
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class RegistrationExtensionsResources {
@@ -40,7 +39,7 @@ internal class RegistrationExtensionsResources {
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
- global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Autofac.RegistrationExtensionsResources", typeof(RegistrationExtensionsResources).GetTypeInfo().Assembly);
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Autofac.RegistrationExtensionsResources", typeof(RegistrationExtensionsResources).Assembly);
resourceMan = temp;
}
return resourceMan;
@@ -70,6 +69,15 @@ internal class RegistrationExtensionsResources {
}
}
+ ///
+ /// Looks up a localized string similar to Expression does not refer to a property.
+ ///
+ internal static string ExpressionDoesNotReferToProperty {
+ get {
+ return ResourceManager.GetString("ExpressionDoesNotReferToProperty", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to The instance registration '{0}' can support SingleInstance() sharing only..
///
diff --git a/src/Autofac/RegistrationExtensionsResources.resx b/src/Autofac/RegistrationExtensionsResources.resx
index bb00ba61b..ba384f101 100644
--- a/src/Autofac/RegistrationExtensionsResources.resx
+++ b/src/Autofac/RegistrationExtensionsResources.resx
@@ -1,17 +1,17 @@
-
@@ -135,4 +135,7 @@
You can only attach a registration predicate to a registration that has a callback container attached (e.g., one that was made with a standard ContainerBuilder extension method).
-
\ No newline at end of file
+
+ Expression does not refer to a property
+
+
diff --git a/test/Autofac.Test/ResolutionExtensionsTests.cs b/test/Autofac.Test/ResolutionExtensionsTests.cs
index d05f87b3c..bfca9a0cc 100644
--- a/test/Autofac.Test/ResolutionExtensionsTests.cs
+++ b/test/Autofac.Test/ResolutionExtensionsTests.cs
@@ -1,7 +1,9 @@
-using Autofac.Core;
+using System;
+using Autofac.Core;
using Autofac.Core.Activators.ProvidedInstance;
using Autofac.Core.Registration;
using Autofac.Test.Scenarios.Parameterisation;
+using Autofac.Test.Scenarios.WithProperty;
using Xunit;
namespace Autofac.Test
@@ -91,5 +93,33 @@ public void WhenPredicateAndValueParameterSupplied_PassedToComponent()
Assert.Equal(a, result.A);
Assert.Equal(b, result.B);
}
+
+ [Fact]
+ public void RegisterPropertyWithExpression()
+ {
+ const string a = "Hello";
+ const bool b = true;
+ var builder = new ContainerBuilder();
+
+ builder.RegisterType()
+ .WithProperty(x => x.A, a)
+ .WithProperty(x => x.B, b);
+
+ var container = builder.Build();
+ var result = container.Resolve();
+
+ Assert.Equal(a, result.A);
+ Assert.Equal(b, result.B);
+ }
+
+ [Fact]
+ public void RegisterPropertyWithExpressionFieldExceptions()
+ {
+ const string a = "Hello";
+ var builder = new ContainerBuilder();
+
+ Assert.Throws(() =>
+ builder.RegisterType().WithProperty(x => x._field, a));
+ }
}
}
diff --git a/test/Autofac.Test/Scenarios/WithProperty/WithProps.cs b/test/Autofac.Test/Scenarios/WithProperty/WithProps.cs
new file mode 100644
index 000000000..eaf2eb6c5
--- /dev/null
+++ b/test/Autofac.Test/Scenarios/WithProperty/WithProps.cs
@@ -0,0 +1,11 @@
+namespace Autofac.Test.Scenarios.WithProperty
+{
+ public class WithProps
+ {
+ public string A { get; set; }
+
+ public bool B { get; set; }
+
+ public string _field;
+ }
+}