// 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);
}
}
}