Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- public interface IConfiguration
- {
- [CanBeNull]
- T GetValue<T>([NotNull] CaseInsensitiveString name);
- void Save([NotNull] CaseInsensitiveString name, [NotNull] object value);
- }
- public static class ConfigurationExtensions
- {
- public static IConfiguration SetValue<T>(this IConfiguration configuration, Expression<Func<T>> expression)
- {
- var value = configuration.GetValue(expression);
- expression.SetValue(value);
- return configuration;
- }
- public static T GetValue<T>(this IConfiguration config, Expression<Func<T>> expression)
- {
- var memberExpr = expression.Body as MemberExpression ?? throw new ArgumentException("Expression must be a member expression.");
- var name = $"{memberExpr.Member.DeclaringType.Namespace}+{memberExpr.Member.DeclaringType.Name}.{memberExpr.Member.Name}";
- return config.GetValue<T>(name);
- }
- }
- public static class MemberSetter
- {
- public static void SetValue<T>([NotNull] this Expression<Func<T>> expression, object value)
- {
- if (expression == null) throw new ArgumentNullException(nameof(expression));
- if (expression.Body is MemberExpression memberExpression)
- {
- var obj = GetObject(memberExpression.Expression);
- switch (memberExpression.Member.MemberType)
- {
- case MemberTypes.Property:
- var property = (PropertyInfo)memberExpression.Member;
- if (property.CanWrite)
- {
- ((PropertyInfo)memberExpression.Member).SetValue(obj, value);
- }
- else
- {
- var bindingFlags = BindingFlags.NonPublic | (obj == null ? BindingFlags.Static : BindingFlags.Instance);
- var backingField = (obj?.GetType() ?? property.DeclaringType).GetField($"<{property.Name}>k__BackingField", bindingFlags);
- if (backingField == null)
- {
- throw new BackingFieldNotFoundException(property.Name);
- }
- backingField.SetValue(obj, value);
- }
- break;
- case MemberTypes.Field:
- ((FieldInfo)memberExpression.Member).SetValue(obj, value);
- break;
- default:
- throw new ArgumentException($"Member must be either a {nameof(MemberTypes.Property)} or a {nameof(MemberTypes.Field)}.");
- }
- }
- else
- {
- throw new ArgumentException($"Expression must be a {nameof(MemberExpression)}.");
- }
- }
- private static object GetObject(Expression expression)
- {
- // This is a static class.
- if (expression == null)
- {
- return null;
- }
- if (expression is MemberExpression anonymousMemberExpression)
- {
- // Extract constant value from the anonyous-wrapper
- var container = ((ConstantExpression)anonymousMemberExpression.Expression).Value;
- return ((FieldInfo)anonymousMemberExpression.Member).GetValue(container);
- }
- else
- {
- return ((ConstantExpression)expression).Value;
- }
- }
- }
- [TestMethod]
- public void Load_InstanceMembers_OnTheType_Loaded()
- {
- var config = new Configuration(new Memory
- {
- { "PublicProperty", "a" },
- { "PrivateProperty", "b" },
- { "PublicField", "c" },
- { "PrivateField", "d" },
- { "PrivateReadOnlyField", "e" },
- });
- var x = new InstanceClass(config);
- config.SetValue(() => x.PublicProperty);
- config.SetValue(() => x.PublicField);
- config.SetValue(() => x.PublicReadOnlyProperty);
- CollectionAssert.AreEqual(new[] { "a", null, "c", null, null, "f" }, x.GetValues().ToList());
- }
- [TestMethod]
- public void Load_InstanceMembers_InsideConstructor_Loaded()
- {
- var config = new Configuration(new Memory
- {
- { "PublicProperty", "a" },
- { "PrivateProperty", "b" },
- { "PublicField", "c" },
- { "PrivateField", "d" },
- { "PrivateReadOnlyField", "e" },
- { "PublicReadOnlyProperty", "f" },
- });
- var x = new InstanceClass(config);
- CollectionAssert.AreEqual(new[] { "a", "b", "c", "d", "e", "f" }, x.GetValues().ToList());
- }
- [TestMethod]
- public void Load_StaticMembers_Loaded()
- {
- var config = new Configuration(new Memory
- {
- { "PublicProperty", "a" },
- { "PrivateProperty", "b" },
- { "PublicField", "c" },
- { "PrivateField", "d" },
- { "PrivateReadOnlyField", "e" },
- { "PublicReadOnlyProperty", "f" },
- });
- config.SetValue(() => StaticClass.PublicProperty);
- config.SetValue(() => StaticClass.PublicField);
- config.SetValue(() => StaticClass.PublicReadOnlyProperty);
- CollectionAssert.AreEqual(new[] { "a", null, "c", null, null, "f" }, StaticClass.GetValues().ToList());
- }
- public class InstanceClass
- {
- public InstanceClass() { }
- public InstanceClass(IConfiguration config)
- {
- config.SetValue(() => PublicProperty);
- config.SetValue(() => PrivateProperty);
- config.SetValue(() => PublicField);
- config.SetValue(() => PrivateField);
- config.SetValue(() => PrivateReadOnlyField);
- config.SetValue(() => PublicReadOnlyProperty);
- }
- public string PublicProperty { get; set; }
- private string PrivateProperty { get; set; }
- public string PublicField;
- private string PrivateField;
- private readonly string PrivateReadOnlyField;
- public string PublicReadOnlyProperty { get; }
- public IEnumerable<object> GetValues()
- {
- yield return PublicProperty;
- yield return PrivateProperty;
- yield return PublicField;
- yield return PrivateField;
- yield return PrivateReadOnlyField;
- yield return PublicReadOnlyProperty;
- }
- }
- public static class StaticClass
- {
- public static string PublicProperty { get; set; }
- private static string PrivateProperty { get; set; }
- public static string PublicField;
- private static string PrivateField;
- private static readonly string PrivateReadOnlyField;
- public static string PublicReadOnlyProperty { get; }
- public static IEnumerable<object> GetValues()
- {
- yield return PublicProperty;
- yield return PrivateProperty;
- yield return PublicField;
- yield return PrivateField;
- yield return PrivateReadOnlyField;
- yield return PublicReadOnlyProperty;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement