// Copyright © 2016 The CefSharp Authors. All rights reserved. // // Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. using System; using System.Collections.Generic; using System.Linq; using System.Reflection; namespace CefSharp.ModelBinding { /// /// Represents a bindable member of a type, which can be a property or a field. /// public class BindingMemberInfo { private readonly PropertyInfo propertyInfo; private readonly FieldInfo fieldInfo; /// /// Gets the name of the property or field represented by this BindingMemberInfo. /// public string Name { get; private set; } /// /// Gets the data type of the property or field represented by this BindingMemberInfo. /// public Type Type { get; private set; } /// /// Constructs a BindingMemberInfo instance for a property. /// /// The bindable property to represent. public BindingMemberInfo(PropertyInfo propertyInfo) { if (propertyInfo == null) { throw new ArgumentNullException("propertyInfo"); } this.propertyInfo = propertyInfo; Type = propertyInfo.PropertyType; Name = propertyInfo.Name; } /// /// Constructs a BindingMemberInfo instance for a field. /// /// The bindable field to represent. public BindingMemberInfo(FieldInfo fieldInfo) { if (fieldInfo == null) { throw new ArgumentNullException("fieldInfo"); } this.fieldInfo = fieldInfo; Type = fieldInfo.FieldType; Name = fieldInfo.Name; } /// /// Sets the value from a specified object associated with the property or field represented by this BindingMemberInfo. /// /// The object whose property or field should be assigned. /// The value to assign in the specified object to this BindingMemberInfo's property or field. public void SetValue(object destinationObject, object newValue) { if (propertyInfo == null) { fieldInfo.SetValue(destinationObject, newValue); } else { propertyInfo.SetValue(destinationObject, newValue, null); } } /// /// Returns an enumerable sequence of bindable properties for the specified type. /// /// The type to enumerate. /// Bindable properties. public static IEnumerable Collect(Type type) { var fromProperties = type .GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(p => p.CanRead && p.CanWrite) .Where(property => !property.GetIndexParameters().Any()) .Select(property => new BindingMemberInfo(property)); var fromFields = type.GetFields(BindingFlags.Public | BindingFlags.Instance).Where(f => !f.IsInitOnly) .Select(field => new BindingMemberInfo(field)); return fromProperties.Concat(fromFields); } } }