ReactivePropertyの初期化が面倒なのでまとめて初期化してみる（Plain Object版）

M <-> VM をBindするのにプロパティ一個一個 `ToReactiveProperty()` していくのが面倒くさい

特に INotifyPropertyChanged を実装できない PlainObject の場合。

```csharp
    public class ReactiveBinder<TSource, TTarget>
    {
        private readonly static Dictionary<string, Action<TSource, TTarget>> binderActions = new Dictionary<string, Action<TSource, TTarget>>();

        static ReactiveBinder()
        {
            BuildBinders();
        }

        public void Bind(TSource source, TTarget target)
        {
            foreach(var action in binderActions)
            {
                action.Value.Invoke(source, target);
            }
        }
        
        private static void BuildBinders()
        {
            var targetType = typeof(TTarget);
            var sourceType = typeof(TSource);
            MethodInfo fromObject = GetBinderMethod(targetType);

            var sourceParameter = Expression.Parameter(sourceType, "$source");
            var targetParameter = Expression.Parameter(targetType, "$destination");
            var modeParameter = Expression.Constant(ReactivePropertyMode.Default);
            var ignoreValidationErrorValue = Expression.Constant(false);

            foreach (var property in targetType.GetProperties())
            {
                var sourceProperty = sourceType.GetProperty(property.Name);
                var sourcePropertyAccessor = Expression.Property(
                    Expression.Convert(sourceParameter, sourceType),
                    property.Name);

                var propertySelector = Expression.Lambda(sourcePropertyAccessor, sourceParameter);

                var genericMethod = fromObject.MakeGenericMethod(new Type[] { sourceType, sourceProperty.PropertyType });
                var fromObjectCall = Expression.Call(genericMethod, sourceParameter, propertySelector, modeParameter, ignoreValidationErrorValue);

                var bindingProperty = Expression.Property(
                    targetParameter,
                    property);

                var assignment = Expression.Assign(bindingProperty, fromObjectCall);

                var lambda = Expression.Lambda<Action<TSource, TTarget>>(
                    assignment,
                    sourceParameter,
                    targetParameter
                    );

                binderActions.Add(property.Name, lambda.Compile());
            }
        }
        private static MethodInfo GetBinderMethod(Type targetType)
        {
            MethodInfo fromObject = null;
            Type[] paramTypes = new Type[] {
                targetType,
                typeof(int),
                typeof(ReactivePropertyMode),
                typeof(bool)
            };
            var flags = BindingFlags.Static | BindingFlags.Public;
            foreach (MethodInfo method in typeof(ReactiveProperty).GetMethods(flags))
            {

                if (method.IsGenericMethod && method.IsGenericMethodDefinition && method.ContainsGenericParameters)
                {
                    if (method.Name == "FromObject" && method.GetParameters().Length == paramTypes.Length)
                    {
                        fromObject = method;
                        break;
                    }
                }
            }
            return fromObject;
        }
    }

```

Refletion と Expressionを駆使してViewModel のプロパティに `ReactiveProperty.FromObject()` の呼び出しを代入していく。

## Example

Model

```csharp
    public class SampleModel
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public DateTime? UpdateDateTime { get; set; }
        public bool Flag { get; set; }
    }
```

ViewModel

```csharp
    public class SampleItemViewModel : BindableBase, INotifyPropertyChanged
    {

        public ReactiveProperty<int> Id { get; set; }
        public ReactiveProperty<string> Name { get; set; }
        public ReactiveProperty<DateTime?> UpdateDateTime { get; set; }
        public ReactiveProperty<bool> Flag { get; set; }

        public SampleItemViewModel()
        {

        }

        public SampleItemViewModel(SampleModel model)
        {
            var binder = new ReactiveBinder<SampleModel, SampleItemViewModel>();
            binder.Bind(model, this);
        }
    }
```

注: FromObjectメソッドを取得するのにパラメータの数の一致だけ見てるけど、オーバーロードはパラメータの数ではなくてパラメータの型をチェックするはずなので破綻する可能性がある。

既にありがちなんだけどまあ Expression の練習と思って。
オブジェクト構築のコストなんぞ、知らん。