reniris
4/13/2018 - 5:13 AM

ReactivePropertyErr

ReactivePropertyErr

using System;
using System.Reactive;
using System.Reactive.Linq;
using MessagePack;
using MessagePack.Formatters;
using MessagePack.ReactivePropertyExtension;
using MessagePack.Resolvers;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Reactive.Bindings;
using TaxPon.Model;
using Xunit;

namespace TaxPonTest
{
    [TestClass]
    public class SettingTest
    {
        [TestMethod]
        public void TestMethod1()
        {
            CompositeResolver.RegisterAndSetAsDefault(
                ReactivePropertyResolver.Instance,
                StandardResolver.Instance
            );

            var s = new Setting();
            //s.Tax.Value = 10;
            var data = MessagePackSerializer.Serialize<Setting>(s);
            var json = MessagePackSerializer.ToJson(data);
            Console.WriteLine(json);
        }
    }

    public class WithRxPropDefaultResolver : IFormatterResolver
    {
        public IMessagePackFormatter<T> GetFormatter<T>()
        {
            return (ReactivePropertyResolver.Instance.GetFormatter<T>()
                 ?? StandardResolver.Instance.GetFormatter<T>());
        }
    }

    [TestClass]
    public class ReactivePropertyTest
    {
        T Convert<T>(T value)
        {
            var resolver = new WithRxPropDefaultResolver();
            return MessagePackSerializer.Deserialize<T>(MessagePackSerializer.Serialize(value, resolver), resolver);
        }

        [TestMethod]
        public void ViewModelTest()
        {
            var vm = new ViewModel(10, 20, 30);

            var deserialized = Convert(vm);
            deserialized.Prop1.Value.Is(10);
            deserialized.Prop2.Value.Is(20);
            deserialized.Prop3.Value.Is(30);
            deserialized.Prop4.Value.Is(60);

            // dump serialized
            var data = MessagePackSerializer.ToJson(vm, new WithRxPropDefaultResolver());

            //  3 = ReactivePropertyMode.DistinctUntilChanged | ReactivePropertyMode.RaiseLatestValueOnSubscribe
            // -1 = UIDispatcherScheduler.Default
            // Prop1:[3, -1, 10]
            // Prop2:[3, -1, 10]
            // Prop3:[3, -1, 10]
            data.Is("[[3,-1,10],[3,-1,20],[3,-1,30]]");
        }

        [TestMethod]
        public void MiscTest()
        {
            var rxCol = new ReactiveCollection<int> { 1, 10, 100 };
            Convert(rxCol).Is(1, 10, 100);
            Convert(Unit.Default).Is(Unit.Default);
            Unit? nullUnit = null;
            Convert(nullUnit).Is(Unit.Default);
        }
    }

    [MessagePackObject]
    public class ViewModel : IMessagePackSerializationCallbackReceiver
    {
        [Key(0)]
        public ReactiveProperty<int> Prop1 { get; private set; }
        [Key(1)]
        public IReactiveProperty<int> Prop2 { get; private set; }
        [Key(2)]
        public IReadOnlyReactiveProperty<int> Prop3 { get; private set; }
        [IgnoreMember]
        public IReadOnlyReactiveProperty<int> Prop4 { get; private set; }

        public ViewModel(int x, int y, int z)
            : this(new ReactiveProperty<int>(x), new ReactiveProperty<int>(y), new ReactiveProperty<int>(z))
        {

        }

        [SerializationConstructor]
        public ViewModel(ReactiveProperty<int> x, IReactiveProperty<int> y, IReadOnlyReactiveProperty<int> z)
        {
            Prop1 = x;
            Prop2 = y;
            Prop3 = z;
            OnAfterDeserialize();
        }

        public void OnAfterDeserialize()
        {
            Prop4 = Prop1.CombineLatest(Prop2, (x, y) => (x + y) * 2).ToReadOnlyReactiveProperty();
        }

        public void OnBeforeSerialize()
        {

        }
    }
}

using Reactive.Bindings;
using Reactive.Bindings.Extensions;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reactive.Linq;
using System.Text;
using System.Threading.Tasks;
using TaxPon.View.Themes;
using System.Reactive.Threading.Tasks;
using System.Reactive.Disposables;
using System.Runtime.Serialization;
using System.IO;
using System.Linq;
using MessagePack;
using MessagePack.ReactivePropertyExtension;
using MessagePack.Resolvers;

namespace TaxPon.Model
{
    [MessagePackObject]
    public class Setting : IDisposable
    {
        /// <summary>
        /// フォントサイズ
        /// </summary>
        [Key(0)]
        public ReactivePropertySlim<int> FontSize { get; } = new ReactivePropertySlim<int>(DefaultValue.FontSize);

        /// <summary>
        /// テーマ
        /// </summary>
        [Key(1)]
        public ReactivePropertySlim<ThemeType> Theme { get; } = new ReactivePropertySlim<ThemeType>(DefaultValue.Theme);

        /// <summary>
        /// カルチャ名
        /// </summary>
        [Key(2)]
        public ReactivePropertySlim<string> CultureName { get; } = new ReactivePropertySlim<string>(DefaultValue.CultureName);

        /// <summary>
        /// 税率
        /// </summary>
        [Key(3)]
        public ReactivePropertySlim<int> Tax { get; } = new ReactivePropertySlim<int>(DefaultValue.Tax);

        /// <summary>
        /// プロパティ変更を監視してファイルにセーブ
        /// </summary>
        [IgnoreDataMember]
        private ReadOnlyReactivePropertySlim<string> SaveProp { get; }

        [IgnoreDataMember]
        private CompositeDisposable Disposable { get; } = new CompositeDisposable();
        
        static Setting()
        {
            CompositeResolver.RegisterAndSetAsDefault(
                ReactivePropertyResolver.Instance,
                StandardResolver.Instance
            );
        }

        public Setting()
        {
            this.FontSize.AddTo(this.Disposable);
            this.Theme.Subscribe(t => Console.WriteLine(t)).AddTo(this.Disposable);
            this.CultureName.AddTo(this.Disposable);

            this.Tax.Subscribe(t => Console.WriteLine("Tax: " + t)).AddTo(this.Disposable);

            //プロパティが変更された場合セーブ
            var s = this.FontSize.CombineLatest(this.Theme, this.CultureName, this.Tax, (a, b, c, d) => SaveAsync(this))
            .Switch()
            .Subscribe(x => Console.WriteLine(x))
            .AddTo(this.Disposable);
        }

        /// <summary>
        /// 設定情報を読み込む
        /// </summary>
        /// <returns></returns>
        public static Setting Load()
        {
            var data = LoadData();
            if (data == null)
            {
                return new Setting();
            }
            else
            {
                return MessagePackSerializer.Deserialize<Setting>(data);
            }
        }

        /// <summary>
        /// ファイルから設定情報を読み込む
        /// </summary>
        /// <returns></returns>
        static protected byte[] LoadData()
        {
            var fullpath = GetDataPath();
            if (File.Exists(fullpath) == false)
            {
                return null;
            }

            // ファイルを読み込む
            return File.ReadAllBytes(fullpath);
        }

        /// <summary>
        /// ユーザーデータ保存フォルダー、サブフォルダ、ファイル名を連結したフルパスを取得する
        /// </summary>
        /// <param name="subfolder">サブフォルダ名</param>
        /// <param name="file">ファイル名</param>
        /// <returns></returns>
        static private string GetDataPath()
        {
            const string SubFolderName = "Save";
            const string FileName = "Config.pack";

            // ユーザーデータ保存フォルダー
            var localFolder = Environment.GetFolderPath(Environment.SpecialFolder.Personal);

            // サブフォルダーを作成、または取得する
            var d = Directory.CreateDirectory(Path.Combine(localFolder, SubFolderName));

            // ファイルを取得する
            var fullpath = Path.Combine(localFolder, SubFolderName, FileName);

            return fullpath;
        }

        /// <summary>
        /// 設定情報をファイルに書き込む
        /// </summary>
        /// <param name="setting">setting</param>
        /// <returns></returns>
        public static async Task<string> SaveAsync(Setting setting)
        {
            Console.WriteLine("SaveAsync");

            var data = MessagePackSerializer.Serialize<Setting>(setting, ReactivePropertyResolver.Instance);

            //return await SaveDataAsync(data);

            return "SaveAsync";
        }

        /// <summary>
        /// ファイルに設定情報を書き出す
        /// </summary>
        /// <param name="data">書き込むデータ</param>
        /// <returns></returns>
        protected static async Task<string> SaveDataAsync(byte[] data)
        {
            var fullpath = GetDataPath();

            using (var fs = new FileStream(fullpath, FileMode.Create, FileAccess.Write, FileShare.Read, 4096, true))
            {
                await fs.WriteAsync(data, 0, data.Length);
            }

            return fullpath;
        }

        public void Dispose()
        {
            Disposable.Dispose();
        }
    }

    public static class DefaultValue
    {
        public const int FontSize = 50;
        public const int Tax = 8;
        public const ThemeType Theme = ThemeType.Dark;
        public static readonly string CultureName = ResourceService.Current.SupportedCultures.First().Name;
    }
}

依存関係の動作「最高 マイナー」
テスト名:	TestMethod1
テストの完全名:	TaxPonTest.SettingTest.TestMethod1
テスト ソース:	C:\Users\yayo\Documents\Visual Studio 2017\Projects\TaxPon\TaxPonTest\SettingTest.cs : 行 19
テスト成果:	失敗
テスト継続時間:	0:00:00.3838875

結果  のスタック トレース:	
場所 TaxPon.Model.Setting..ctor()
   場所 TaxPonTest.SettingTest.TestMethod1() 場所 C:\Users\yayo\Documents\Visual Studio 2017\Projects\TaxPon\TaxPonTest\SettingTest.cs:行 25
結果  のメッセージ:	
テスト メソッド TaxPonTest.SettingTest.TestMethod1 が例外をスローしました: 
System.IO.FileLoadException: ファイルまたはアセンブリ 'ReactiveProperty, Version=4.0.0.0, Culture=neutral, PublicKeyToken=910d1732782c71cb'、またはその依存関係の 1 つが読み込めませんでした。見つかったアセンブリのマニフェスト定義はアセンブリ参照に一致しません。 (HRESULT からの例外:0x80131040)

依存関係の動作「最高 パッチ」
テスト名:	TestMethod1
テストの完全名:	TaxPonTest.SettingTest.TestMethod1
テスト ソース:	C:\Users\yayo\Documents\Visual Studio 2017\Projects\TaxPon\TaxPonTest\SettingTest.cs : 行 19
テスト成果:	失敗
テスト継続時間:	0:00:02.0791839

結果  のスタック トレース:	
場所 TaxPon.Model.Setting..ctor()
   場所 TaxPonTest.SettingTest.TestMethod1() 場所 C:\Users\yayo\Documents\Visual Studio 2017\Projects\TaxPon\TaxPonTest\SettingTest.cs:行 25
結果  のメッセージ:	
テスト メソッド TaxPonTest.SettingTest.TestMethod1 が例外をスローしました: 
System.IO.FileLoadException: ファイルまたはアセンブリ 'ReactiveProperty, Version=4.0.0.0, Culture=neutral, PublicKeyToken=910d1732782c71cb'、またはその依存関係の 1 つが読み込めませんでした。見つかったアセンブリのマニフェスト定義はアセンブリ参照に一致しません。 (HRESULT からの例外:0x80131040)

依存関係の動作「最低」
テスト名:	TestMethod1
テストの完全名:	TaxPonTest.SettingTest.TestMethod1
テスト ソース:	C:\Users\yayo\Documents\Visual Studio 2017\Projects\TaxPon\TaxPonTest\SettingTest.cs : 行 19
テスト成果:	失敗
テスト継続時間:	0:00:00.1739282

結果  のスタック トレース:	
場所 TaxPon.Model.Setting..ctor()
   場所 TaxPonTest.SettingTest.TestMethod1() 場所 C:\Users\yayo\Documents\Visual Studio 2017\Projects\TaxPon\TaxPonTest\SettingTest.cs:行 25
結果  のメッセージ:	
テスト メソッド TaxPonTest.SettingTest.TestMethod1 が例外をスローしました: 
System.IO.FileLoadException: ファイルまたはアセンブリ 'ReactiveProperty, Version=4.0.0.0, Culture=neutral, PublicKeyToken=910d1732782c71cb'、またはその依存関係の 1 つが読み込めませんでした。見つかったアセンブリのマニフェスト定義はアセンブリ参照に一致しません。 (HRESULT からの例外:0x80131040)

依存関係の動作「最高」
テスト名:	TestMethod1
テストの完全名:	TaxPonTest.SettingTest.TestMethod1
テスト ソース:	C:\Users\yayo\Documents\Visual Studio 2017\Projects\TaxPon\TaxPonTest\SettingTest.cs : 行 19
テスト成果:	失敗
テスト継続時間:	0:00:00.7376276

結果  のスタック トレース:	
場所 MessagePack.FormatterResolverExtensions.GetFormatterWithVerify[T](IFormatterResolver resolver)
   場所 MessagePack.Formatters.TaxPon_Model_SettingFormatter1.Serialize(Byte[]& , Int32 , Setting , IFormatterResolver )
   場所 MessagePack.MessagePackSerializer.Serialize[T](T obj, IFormatterResolver resolver)
   場所 MessagePack.MessagePackSerializer.Serialize[T](T obj)
   場所 TaxPonTest.SettingTest.TestMethod1() 場所 C:\Users\yayo\Documents\Visual Studio 2017\Projects\TaxPon\TaxPonTest\SettingTest.cs:行 27
結果  のメッセージ:	
テスト メソッド TaxPonTest.SettingTest.TestMethod1 が例外をスローしました: 
System.IO.FileLoadException: ファイルまたはアセンブリ 'ReactiveProperty, Version=3.4.0.0, Culture=neutral, PublicKeyToken=null'、またはその依存関係の 1 つが読み込めませんでした。厳密な名前付きのアセンブリが必要です。 (HRESULT からの例外:0x80131044)