HIDORI on The Web

マネージコードしか書きたくない

Pseudo Live SDK version 0.6.1.1 をリリースしました

without comments

Pseudo Live SDK version 0.6.1.1 をリリースしました。

Pseudo Live SDK は、WPF や Windows.Forms, コンソールアプリケーションをサポートする Live SDK クローンです。

Live SDK の “Managed API” のサポート対象は Windows 8 の Metro スタイルアプリケーションと Windows Phone アプリケーションであり、Windows 7 やそれ以前の環境で動作する一般的なデスクトップアプリケーション(WPF や Windows.Forms, コンソールアプリケーション)はサポート対象外です。

Pseudo Live SDK は、 Windows 7 などで動作するそれら「対象外」のアプリケーションに対して、Live SDK の “Managed API” 相当の API を提供します。Pseudo Live SDK を使用すれば、オリジナルの Live SDK と同じように、アプリケーションから SkyDrive に保存されたファイルや Hotmail のアドレス帳、カレンダーなどの情報にアクセスすることが出来ます。

主な変更点

今回のリリースにおける、主な変更点は以下のとおりです。

  • T4 によるコード生成を導入
  • 単体テストを増強
  • "BeginGet" および "EndGet" の使用方法を紹介する、 "MeConsoleApplication2" サンプルを追加
  • LiveConnectClientAsyncResult.WaitHandle のリークを修正。@dilbert_124 さんに感謝
  • LiveConnectItem.LiveConnectItem のバグを修正
  • LiveOperationProgress.ProgressPercentage のバグを修正
  • クラス名やメンバ名など、いくつかのスペルミスを修正 ;-p

ダウンロード

Pseudo Live SDK は、以下よりダウンロードすることが出来ます。

インストール

あなたのプロジェクトで Pseudo Live SDK を利用するためには、以下を手順を実行します。

  • PseudoLiveSDK-0.6.1.1-bin.zip をダウンロード
  • 上記ファイルを解凍して、Mjollnir.Live.dll を取り出す
  • Mjollnir.Live.dll を、あなたのプロジェクトの「参照設定」に追加する

NuGet が利用可能なら、Pseudo Live SDK のインストールはもっとずっと簡単です。

NuGet Package Console で以下のコマンドを実行すると、プロジェクトに Pseudo Live SDK が追加されます。

Install-Package PseudoLiveSDK

あるいは、NuGet Package Manager が導入済みなら、”NuGet official package source” から “Pseudo Live SDK” を検索して、インストールを行なってください。

動作環境

Pseudo Live SDK は、以下の環境で動作することを願って作成されています。

  • Windows XP SP3 以上, Windows 7, Windows 8 Consumer Preview
  • .NET Framework 3.5 SP1, .NET Framrwork 4.0 (Client Profile は対象外)
  • WPF, Windows.Forms, コンソールアプリケーション

技術情報

以下より、Live SDK 関連の技術情報を参照することが出来ます。

Written by Hiroaki SHIBUKI

5月 20th, 2012 at 5:28 pm

Pseudo Live SDK version 0.6.0.1 をリリースしました

without comments

Pseudo Live SDK version 0.6.0.1 をリリースしました。

Pseudo Live SDK は、WPF, Windows.Forms および Console Application をサポートする Live SDK クローンです。

オリジナルの Live SDK は WPF, Windows.Forms および Console Application のサポートを含んでいませんが、Pseudo Live SDK は WPF, Windows.Forms および Console Application をすべてサポートします。

Pseudo Live SDK はオリジナルの Live SDK と同じく、アプリケーションへの Windows Live ID によるシングルサインオン (SSO) の統合や、SkyDrive, Hotmail, Windows Live Messanger 内のデータにアクセスを行うための API を提供します。

主な変更点

今回のリリースにおける、主な変更点は以下のとおりです。

  • SyncronizationContext を導入、イベントハンドラ内での "Invoke" や "BeginInvoke" が不要に
  • "BeginGet" や "EndGet" など、APM (非同期プログラミングモデル) 型のメソッドを追加
  • 単体テストを増強
  • サンプルを更新。新たに "SkyDriveWindowsFormsApplication1" サンプルを追加。

以下のスクリーンショットは、Pseudo Live SDK に含まれている "SkyDriveWindowsFormsApplication1"  サンプルのものです。

2012-05-16-01

ダウンロード

Pseudo Live SDK は、以下よりダウンロードすることが出来ます。

  • Pseudo Live SDK project home
  • SkyDrive
    • ソースファイル(クラスライブラリ+単体テスト+サンプル)
    • バイナリ(クラスライブラリのアセンブリ+サンプルの実行ファイル)

概要

Pseudo Live SDK には、以下のクラスが含まれています。

  • SignInDialog は、Windows Live ID によるサインイン ダイアログを表示します。
  • LiveConnectSession は、セッション情報をカプセルします。
  • LiveConnectClient は、SkyDrive や otmail, Windows Live Messenger 内のデータにアクセスします。
  • EventArgs 派生クラス、etc …

動作環境

Pseudo Live SDK は、以下の環境で作動することを願って作成されています。

  • Windows XP SP3 以上, Windows 7, Windows 8 Consumer Preview
  • .NET Framework 3.5 SP1, .NET Framrwork 4.0 (Client Profile は対象外)
  • WPF, Windows.Forms, Console Application

技術情報

以下より、Live SDK 関連の技術情報を参照することが出来ます。

Written by Hiroaki SHIBUKI

5月 17th, 2012 at 12:23 am

lock と戻り値の受け取りを簡潔に

without comments

またまた、ボクのキライなパターンである

var value = default(int);

lock (context)
{
    value = context.GetValue();
}

みたいなコードを書かねばならない局面がやってきました。

でもそんなコードは書きたくない!書きたくないものは書きたくない!

ということで、いつも通り

という小さなクラスを書きました。

これを使えば、前出のイヤンな感じのコードは

var value = Lock.Invoke(context, () =>
{
    context.GetValue();
});

のような、お好みのスタイルで書くことができます。

メデタシ (^o^)

Written by Hiroaki SHIBUKI

5月 12th, 2012 at 1:28 pm

Posted in 技術情報

Tagged with

Pseudo Live SDK version 0.5.0.3 をリリースしました

without comments

Pseudo Live SDK version 0.5.0.3 をリリースしました。

Pseudo Live SDK は、Windows.Forms, WPF, および Console Application をサポートする Live SDK クローンです。

オリジナルの Live SDK は Windows.Forms, WPF, および Console Application のサポートを含んでいませんが、Pseudo Live SDK は Windows.Forms, WPF, および Console Application をサポートします。

Pseudo Live SDK はオリジナルの Live SDK と同じく、アプリケーションへの Windows Live ID によるシングルサインオン (SSO) を統合や、SkyDrive, Hotmail, Windows Live Messanger 内のデータにアクセスを行うための API を提供します。

ダウンロード

Pseudo Live SDK は、以下よりダウンロードすることが出来ます。

Pseudo Live SDK project home
http://PseudoLiveSDK.codeplex.com/

概要

Pseudo Live SDK には、以下のクラスが含まれています。

  • LiveAuthDialog は、Windows Live ID によるサインインのためのダイアログを表示します。
  • LiveConnectSession は、Windows Live ID セッションをカプセルします。
  • LiveConnectClient は、SkyDrive や otmail, Windows Live Messenger 内のデータにアクセスします。
  • EventArgs 派生クラス、etc …

動作環境

Pseudo Live SDK は、以下の環境で作動することを願って作成されています。

  • Windows XP SP3 以上, Windows 7, Windows 8 Consumer Preview
  • .NET Framework 3.5 SP1, .NET Framrwork 4.0 (Client Profile は対象外)

技術情報

以下より、技術情報を参照することが出来ます。

Written by Hiroaki SHIBUKI

5月 12th, 2012 at 3:11 am

Task の完了待ちを簡潔に

without comments

TPM な API のテストを書いていて、

var client = new LiveConnectClient(session);

var task = client.Get("me");

task.Wait();

var result = task.Result;

// 実行結果の評価

のようなコード=タスクの完了待ち合わせと処理結果の取得を大量に書く羽目になりました。

塵も積もれば。。。で、こんなんいくつも書くとかイヤすぎです。

書きたいことだけを簡潔に書きたい!

ということで

なんてのを書いてみました。

async, await ではあまにりに大規模なコンパイラの暗躍があるので、テストプロジェクトで使うならこれくらいスケスケの作りの方が、なにかと都合がよかったり。

で、これを使うと「Task 完了の待ち合わせと処理結果の取得」は

var result = client.Get("me").Await();

// 実行結果の評価

のように書けます。

これはかなりシンプルになりますネ!

ちなみに、テストプロジェクトで使うことはなさそーですが、Task.Start() と Task.Wait() のオーバーロードをサポートするバージョンも T4 を使って書いてみました。

Written by Hiroaki SHIBUKI

5月 10th, 2012 at 2:51 pm

バイト配列の組立を簡潔に

without comments

「文字列の組み立てを簡潔に」と似たような感じのノリ。

たとえば

var bytes = default(bytes[]);

using (var stream = new MemoryStream())
{
    using (var writer = new StreamWriter(stream))
    {
        writer.WriteLine("ROCK'N ROLL!");
    }

    bytes = stream.ToArray();
}

みたいのは

というクラスを定義しておくと

var bytes = ByteArrayFactory.Create(stream =>
{
    using (var writer = new StreamWriter(stream))
    {
        writer.WriteLine("ROCK'N ROLL!");
    }
});

のように書けて、大変気持よいデス。

# 別に using がキライなわけじゃないんだけど、どうしてこーなるんだろう? (^^;;;

Written by Hiroaki SHIBUKI

5月 9th, 2012 at 1:37 am

Posted in 技術情報

Tagged with

非同期呼び出しの待ち合わせを簡潔に

without comments

「非同期呼び出しを行い、すぐさまその完了を待ち合せたいたい」ことって、ありますよね?

ボクはあります。

昨夜、非同期メソッドのテストを書いていて、そういう状況になりました。

よく使うパターンは

var client = new LiveConnectClient(session);

using (var signal = new ManualResetEventSlim(false))
{
    client.GetCompleted += (s, e) =>
    {
        // 完了後の処理
        signal.Set();
    };

    client.GetAsync(address);
    signal.Wait();
}

なわけですが、似たような記述を何個も書いていると滅入ってきます。

この局面における重点事項は「非同期呼び出しの完了を待ち合わせる」ことであって、ManulResetEventSlim のインスタンス生成とか、その Wait() とか、余分なことは極力意識したくないわけです。

書きたいことだけを、簡潔に書きたい!(w

そこで、以下のようなクラスを定義します。

Gist のソースを見る。


これを使うと、「非同期呼び出しの完了を待ち合わせ」問題は

 

var client = new LiveConnectClient(session);

Syncronized.Invoke(signal =>
{
    client.GetCompleted += (s, e) =>
    {
        // 完了後の処理
        signal.Set();
    };

    client.GetAsync(address);
});

のように、ごく簡潔に記述することが出来ます。

これで、単調なテストの記述もいくらか低減されるとゆーものですw

Written by Hiroaki SHIBUKI

5月 8th, 2012 at 11:33 pm

文字列の組み立てを簡潔に

with one comment

BCL には、文字列を組み立てを支援する StringBuilder クラスが含まれています。

機能的にはこれで不満はありませんが、複数の文字列を並行して組み立てる場合には複数の StringBuilder クラスのインスタンスを使うことになり、それらの変数名をどうするかなどの非常に深刻な問題が発生します。

たとえば

var sb1 = new StringBuilder();

sb1.Append("ほげ");
sb1.Append("ほげ");

var sb2 = new StringBuilder();

sb2.Append("ほげ");
sb2.Append("ほげ");

var head = sb1.ToString();
var tail = sb2.ToString();

のような打算的な解決はノーグッドです。

var sbHead = new StringBuilder();

sbHead.Append("ほげ");
sbHead.Append("ほげ");

var sbTail = new StringBuilder();

sbTail.Append("ほげ");
sbTail.Append("ほげ");

var head = sbHead.ToString();
var tail = sbTail.ToString();

も本質変わらずで、美しさに欠けています。

感覚的には

var head = default(string);

{
    var sb = new StringBuilder();

    sb.Append("ほげ");
    sb.Append("ほげ");

    head = sb.ToString();
}

var tail = default(string);

{
    var sb = new StringBuilder();

    sb.Append("ほげ");
    sb.Append("ほげ");

    tail = sb.ToString();
}

が理想に一番近いものの、かえってコードが長くなっているのは大きなマイナスです。

head や tail の初期化が無駄な点も気になります。(「var を使わない」という選択は却下w)

そもそも、この局面における最重点事項は「head, tail という2つの文字列を組み立てること」であって、StringBuilder のインスタンス生成みたいな些事はできる限り意識したくありません。

もっと簡潔に、書きたいことだけを書きたい!(w

そこで、以下のようなファクトリメソッドを定義します。

これを使うと、「複数の文字列の組立」問題は

var head = StringFactory.Create(sb =>
{
    sb.Append("ほげ");
    sb.Append("ほげ");
});

var tail = StringFactory.Create(sb =>
{
    sb.Append("ほげ");
    sb.Append("ほげ");
});

のように、ごく簡潔に記述することができます。

ヤル気倍増ですネw

Written by Hiroaki SHIBUKI

5月 8th, 2012 at 4:23 pm

Posted in 技術情報

Tagged with

Pseudo Live SDK 制作開始

with one comment

SkyDrive for Windows が公開されたことで、刺激を受けました。

Live SDK を使えば、ユーザプログラムから SkyDrive を操作することが出来る」というのは、以前から知識としては知っていたため、早速 Live SDK をダウンロードしてみました。

んがしかし、Live SDK の中を見てびっくり。「Windows Forms のサポートが含まれていない」という衝撃の事実が発覚。

それにしても、まだ正式リリースされてもいない Windows 8 Metro Style アプリケーション向けのライブラリが含まれてるってゆーのに、歴史ある Windows Forms サポートが含まれてのはなんとも…

企業戦略だとしても、ちょっと厳しすぎな気が ;-p

なんてことを言っても今更どーにもなりそーもないので、気を取り直して

  • Windows コンソールアプリケーション
  • Windows Forms アプリケーション

そしてたぶん WPF アプリケーションでも利用可能な Live SDK 「もどき」を作ることにしました。

ライブラリ実装のお手本は、本家 Live SDK の Windows Phone 向けライブラリです。

LiveAuthClient クラスによる認証部分は、そのまま移植してもいいことなさそうなので、完全オリジナルとしました。

LiveConnectSession, LiveConnectClient クラスによる REST API へのアクセスについては、できる限りオリジナルと同じような動作を目指すこととします。

で、とりあえずなんとか

  • LiveAuthDialog クラスによるサインイン
  • LiveConnectClient.GetAsync() メソッドによるコンテンツ取得
  • LiveConnectClient.DownloadAsync() メソッドによるコンテンツ取得

まで出来たので、ソリューションを SkyDrive で公開します。

サインイン

サインインには、LiveAuthDialog クラスを使用します。

以下は、LiveAuthDialog クラスによるサインインのサンプルコードです。

var session = default(LiveConnectSession);

using (var dialog = new LiveAuthDialog())
{
    dialog.ClientId = "<Your Client ID>";
    dialog.Scopes = new[] { "wl.signin" };
    dialog.RedirectUri = new Uri("http://oauth.live.com/desktop");
    dialog.Locale = "ja";

    if (dialog.ShowDialog() != DialogResult.OK)
    {
        if (dialog.Error != null)
        {
            Console.WriteLine(dialog.Error.Message);
        }
        else
        {
            Console.WriteLine("操作がキャンセルされました。");
        }

        return;
    }

    session = dialog.Session;
}

LiveAuthDialog クラスは、Windows Forms ダイアログの典型的な実装です。

インスタンス生成した後にパラメータ設定を行い、ShowDialog() メソッドでサインインダイアログの表示を行います。

2012-05-06-01

サインインを正常に完了すると、Session プロパティに有効な LiveConnectSession クラスのインスタンスが返ります。

サインインを完了する前にサインインダイアログを閉じたり、認証エラーが発生した場合などに、ShowDialog() は DialogResult.Cancel を返します。

認証エラーが発生した場合、Error プロパティにはエラーの詳細を示す例外オブジェクトが返ります。

LiveConnectClient クラスのインスタンス生成

SkyDrive に保存されたファイルなど、Windows Live のコンテンツ操作には LiveConnectClient クラスを使用します。

LiveConnectClient クラスは、Live Connect REST API の汎用ラッパです。LiveConnectClient クラスが公開する GetAsync(), DownloadAsync() などのメソッドを利用して、Windows Live のコンテンツ操作を行います。

以下は、LiveConnectSession クラスのインスタンスを使用して LiveConnectClient クラスのインスタンスを作成するサンプルコードです。

var connect = new LiveConnectClient(session);

LiveConnectClient.GetAsync() によるアカウント情報の取得

LiveConnectClient.GetAsync() メソッドは、SkyDrive に保存されたファイルのメタ情報の取得など、JSON 形式の応答を返す API  呼び出しに適しています 。

GetAsync() メソッドは非同期 API であるため、GetCompleted イベントを使用して、GetAsync() メソッドの実行完了を待ち合わせます。

以下は、LiveConnectClient.GetAsync() メソッドによるアカウント情報取得のサンプルコードです。

var result = default(IDictionary);

using (var signal = new ManualResetEventSlim(false))
{
    connect.GetCompleted += (s, e) => { result = e.Result; signal.Set(); };
    connect.GetAsync("me");

    signal.Wait();
}

foreach (var key in result.Keys)
{
    Console.WriteLine(string.Format("{0}={1}", key, result[key]));
}

LiveConnectClient.DownloadAsync() によるアカウント情報の取得

LiveConnectClient.DownloadAsync() メソッドは、SkyDrive に保存されたファイル本体など、Live Connect REST API からの応答をバイトストリームで受け取りるのに適しています。

DownloadAsync() メソッドは非同期 API であるため、DownloadCompleted イベントを使用して、DownloadAsync() メソッドの実行完了を待ち合わせます。

また、DownloadProgressChanged イベントを使用して、バイトストリームのダウンロードの進捗を知ることも可能です。

以下は、LiveConnectClient.DownloadAsync() メソッドによるアカウント情婦取得のサンプルコードです。

var result = default(Stream);

using (var signal = new ManualResetEventSlim(false))
{
    connect.DownloadCompleted += (s, e) => { result = e.Result; signal.Set(); };
    connect.DownloadProgressChanged += (s, e) => Console.WriteLine("{0}/{1} - {2}%", e.BytesRecieved, e.TotalBytesToRecieve, e.ProgressPercentage);
    connect.DownloadAsync("me");

    signal.Wait();
}

using (var stream = new MemoryStream())
{
    result.CopyTo(stream);
    Console.WriteLine(stream.ToArray().Length);
}

result.Close();

Written by Hiroaki SHIBUKI

5月 6th, 2012 at 4:02 am

Dictionary<TKey, TValue>.ContainsKey() とかの「モヤっ」

without comments

拡張メソッドを使った小ネタです。

Dictionary<TKey, TValue> を使っていて

  if (dictionary.ContainsKey("key1")) hoge.Value1 = dictionary["key1"];
  if (dictionary.ContainsKey("key2")) hoge.Value2 = dictionary["key2"];

みたいな感じのコードを書いていて、なんとなく「モヤっ」とした気持ちになりました。

そこで

public static void InvokeIfContainsKey(
    this IDictionary<TKey, TValue> source, TKey key, Action<TValue> action)
{
  if (source.ContainsKey(key))
  {
    action(source[key]);
  }
}

という拡張メソッドを定義して、前出のコードを

dictionary.InvokeIfContainsKey("key1", value => hoge.Value1 = value);
dictionary.InvokeIfContainsKey("key2", value => hoge.Value2 = value);

のように書きかえました。

で、少しだけ「モヤっ」が解消。

# 決して記述が短くなったわけではない点に注意 (^^;;;

Written by Hiroaki SHIBUKI

5月 3rd, 2012 at 2:09 pm

Posted in 技術情報

Tagged with