2008年3月25日火曜日

[他]ソースの整形ツール(blog用?)

いままで、blogにソースを掲載するとき<pre>を自分で書きそのままソースを貼り付けていました。

しかし、VS.NETのようにコードをカラー表示するとblogが見やすくなります。そこで調べてみると、コードからHTMLに変換するようなツールがいろいろあることがわかりました。

VS.NET2005以降の場合、アドオンツールがあり、コレ(リンク先失念)を導入するのがよいと思います。

ただし、アドオン機能なのでExpress Editionではサポートされません。
残念ならが製品版を持っていないので、私は利用することが出来ません。。。

そのため、ソース変換のサービスを利用しています。このblogではここを利用させてもらっています。ほかにもC# code formatなど有名なサイトがあります。

2008年3月21日金曜日

[.NET]SQLServer2005のクエリ通知機能

SQLServer2008 CTP版がすでに世の中に出ていますが、そのあたりは気にせず、SQLServer2005のクエリ通知機能について調査してみました。
サンプルソースを作って。。。と思いましたが、環境を作ったりする時間が取れそうにないので、とりあえずメモだけ。

クエリ通知機能とは特定のテーブルテーブルに更新が合った場合にSQLServer側からイベントを発行してくれるような機能のようです。
ソケット通信に着替えると、サーバ(SQLServer)がUDPで更新情報を流しでクライアント(ADO.NET)がそれを受けてイベント発火。といったとことでしょうか。

詳細はここが参考になります。
で、クライアント側の処理を簡単に手順をまとめると、
  1. DBをオープンする
  2. 参照用のSqlCommandを生成する。SQL→「WAITFOR ( RECEIVE * FROM ContactChangeMessages);」
  3. SqlCommandにそれらしくCommandTimeoutを設定する
  4. SqlCommand.ExecuteReaderする
  5. SqlDataReader.Read()する。結果がtrueであれば結果有

※データベースに対して通知機能を有効にする必要があります。

おおざっぱにはこんな感じです。

アプリケーションサーバが複数台の構成になっていて、データを更新するたびに何かしら通知するような仕組みが必要な(つくりが悪い説もありますが。。。)場合、比較的楽に実装できそうですね。

2008年3月18日火曜日

[.NET]イベント実装の2つの方法

コントロールの場合、独自イベントを発行する方法は2種類あります。
どちらの方法で実装しても結果は同じです。
「EventHandlerを独自で定義する方法」は、コントロールでなくても実装できるため汎用性が高く、実装も若干少なめです。しかし「EventHandlerをプロパティに保存する方法」はコントロールのそもそも持っているプロパティを使用するので何となくですが、自然な気がします。

・・・まぁどっちでもいいんですけどね。。。

以下サンプル。

■EventHandlerを独自で定義する方法
/// <summary>
/// EventHandlerを独自で定義する方法
/// </summary>
public partial class TextBoxEx2 : TextBox
{
    //イベントハンドラの定義
    public event EventHandler OnReturn;

    /// <summary>
    /// コンストラクタ
    /// </summary>
    public TextBoxEx2()
    {
        InitializeComponent();
    }

    /// <summary>
    /// キー押下
    /// </summary>
    protected override void OnKeyPress(KeyPressEventArgs e)
    {
        // リターンキー押下だったらイベント発行する
        if (e.KeyChar == '\r')
        {
            e.Handled = true;
            DoReturn();
            return;
        }
        base.OnKeyPress(e);
    }

    /// <summary>
    /// リターンキーイベント
    /// </summary>
    protected virtual void DoReturn(){
        if (OnReturn != null)
        {
            //イベントを発生させます
            OnReturn(thisEventArgs.Empty);
        }
    }
}


■EventHandlerをプロパティに保存する方法
/// <summary>
/// EventHandlerをプロパティに保存する方法
/// </summary>
public partial class TextBoxEx1 : TextBox
{
    /// <summary>
    /// イベント識別用キー変数
    /// </summary>
    private static readonly object EventOnReturn = new object();
    /// <summary>
    /// イベントハンドラー設定プロパティ
    /// </summary>
    public event EventHandler OnReturn
    {
        add { base.Events.AddHandler(EventOnReturnvalue); }
        remove { base.Events.RemoveHandler(EventOnReturnvalue); }
    }

    /// <summary>
    /// コンストラクタ
    /// </summary>
    public TextBoxEx1()
    {
        InitializeComponent();
    }

    /// <summary>
    /// キー押下
    /// </summary>
    protected override void OnKeyPress(KeyPressEventArgs e)
    {
        // リターンキー押下だったらイベント発行する
        if (e.KeyChar == '\r')
        {
            e.Handled = true;
            DoReturn();
            return;
        }
        base.OnKeyPress(e);
    }

    /// <summary>
    /// イベント発火処理
    /// </summary>
    protected virtual void DoReturn()
    {
        //該当のイベントハンドラを取得
        EventHandler handler = (EventHandler)base.Events[EventOnReturn];
        //イベント発火
        if (handler != null)
        {
            handler(thisEventArgs.Empty);
        }
    }
}

2008年3月15日土曜日

[.NET]列挙体をフラグっぽく使う

C/C++では、数値をビット列に見立てて操作することがあります。
たとえばこんな感じ。

WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW


C#では、列挙体の型指定をつけた上で、それらしいことができます。
(値は適当です。)

[Flags]
public enum WNDClass {
    None = 0x00000000,
    Hredraw = 0x00000001,
    Vredraw = 0x00000002,
    foo = 0x00000004,
    bar = 0x00000008,
    WindowClass = Hredraw | Vredraw,
}


引数を渡すときにorすることもできます。

//呼び出し元 引数をorで渡しちゃう
bool result = CreateWindow("abc"WNDClass.Hredraw | WNDClass.Vredraw);


//呼び出し先
public bool CreateWindow(string titleWNDClass cls){
    //・・・処理
    return true;
}


・・・知りませんでした。

2008年3月12日水曜日

[.NET]Reflectionでprivateフィールドに値を突っ込む

.NET Frameworkのクラスや、提供されているライブラリを使った単体テストをしようとした場合、時々、privateなフィールドを強制的に変更したい場合があります。そんなときにReflectionを使います。
コードはこんな感じ。

//呼び出し元
HogeEx he = new HogeEx();
Type tp = typeof(Hoge);
FieldInfo info = tp.GetField("_bar"BindingFlags.SetField | BindingFlags.NonPublic | BindingFlags.Instance);
info.SetValue(hetrue);

internal class Hoge
{
    // Fields
    public bool _foo = true;
    private bool _bar = false;
}

internal class HogeEx : Hoge
{
    // Fields
    public bool _fooEx = true;
    private bool _barEx = false;
}


ポイントとしては、

  1. 実際にprivateフィールドを持っているクラスのタイプを指定する

  2. Type.GetField()の第二引数に、BindingFlags.Instance|BindingFlags.NonPublicを指定する

  3. 値を突っ込む場合、↑に加え、BindingFlags.SetFieldを指定する

です。

たとえば、HttpRequestのFormに対して強引に値を突っ込みたい場合を考えてみます。HttpRequestのプロパティForm(NameValueCollectionの派生クラス)は参照のみの仕様です。値をセットしようとすると例外が発生します。これは、Form(NameValueCollection)のベースクラスであるNameObjectCollectionBaseのReadOnlyプロパティにより制御しています。そのプロパティの元はprivate変数の_readOnlyとなります。これにfalseを設定すればよい。ということになります。



HttpRequest req = new HttpRequest("""http://localhost/"""); //適当なURLが指定できないのでlocalhostを指定
Type tp = typeof(NameObjectCollectionBase);
FieldInfo info = tp.GetField("_readOnly"BindingFlags.SetField | BindingFlags.NonPublic | BindingFlags.Instance);
info.SetValue(req.Formfalse);
req.Form.Add("foo""bar");

2008年3月10日月曜日

[他]アクセスカウンタ設置

今日の昼、このblogにアクセスカウンタを設置してみました。
半日経過しましたが、意外なことに10件程度アクセスがありました。もっと少ないと思っていました。

今度は、コメントがもらえるようにがんばらねば。。。

2008年3月8日土曜日

[.NET]OracleClient

.NET用のOracleClentといえば、真っ先にODP.NETを思い浮かべます。というかちょっと前まで、ODP.NETを使う方法以外知りませんでした。でその後、掲示板やサイトの情報から結構いろんな物があることがわかりました。
簡単に書くと以下のとおりです。
  1. ODP.NET
  2. ODBC
  3. Instant Client

ODP.NETは省略しますが、.NETの時代になっても生き残っていたODBC。Orale独自の機能は使えなくなってしまいますが、プロバイダをそれらしく指定すれば接続できることをいまさらながら知りました。MDBとかと同じ方法ですね。

で次にOracle Instant Clientですが、コレもOracle社より提供されているクライアントなんですが、なんとインストール不要なんです。提供もzip形式ですし、コピー+path設定で動作させることが出来るようです。ODP.NETはこのクライアントのインストールがあるので、クライアントアプリケーションを配布するのがメンドウだったんですが、コレを使えば利便性がが上がるようです。Oracle Instant Clientの使い方は、ここが参考になります。

Oracle Instant ClientでもOracle独自機能は使えるんだろうか。。。今度試してみよう。

・・・いつの間にかODP.NET 11系がリリースされている!。10系ではVistaでまともに動作しなかったのですが、対応されているのだろうか。。。

2008年3月7日金曜日

[他]SVN+VS.NET その4

VS2005+AnkhSVN環境の人に朗報。
なんと、日本語パッチを開発してくれた人がいます!!
パッチはIILdotJPさんよりダウンロードできます。
インストーラはありませんが、アセンブリを差し替えることにより日本語化します。

私の環境はWindowsXP SP2/VS2005ですが正常動作してますね。

2008年3月6日木曜日

[.NET]ASP.NETのfontタグ

ASP.NETをデザイナで編集していると、なぜかわかりませんが、<font>が勝手に挿入されてしまいます。その回避策が@itの掲示板に紹介されていましたので、コレをメモ。

<body style="font-family: MS UI Gothic;">


の一文で回避できるそうな。
掲示板でも紹介されていますが、最後に取り忘れないように注意!!

2008年3月5日水曜日

[Java]NTLM 認証

Windowsには、Windows統合認証というモードがあります。
コレはドメインに参加するときやIISを使ったWebシステムを透過的に認証出来る機構です。
シングルサインオンともいいますね。

で、Windows上での動作に限りますが、Java系のWebシステムでもこの統合認証を利用することが出来るみたいです。
詳しくは、Sunのサイトになりますがここここが参考になりそうです。

2008年3月1日土曜日

[.NET]自動トランザクション(ServicedComponent)

.NET Frameworkでは自動トランザクションとよばれる機構があります。まぁ簡単に言うと2フェーズコミットを実現する分散トランザクション機構です。
私の知る限り、.NET Framework3.5までの、実装方法は2種類の方法があります。

  1. System.Transactions.TransactionScopeを使う方法(新しい2.0系)
  2. System.EnterpriseServices.ServicedComponentを継承する方法(古い1.1系)


以前「1.」を.NET2.0+ODP.NETで利用したことがありました。そのときはC#との相性のよさと、使い勝手のよさに感動しました。しかし、今回、.NET1.1系の仕事であったため「2.」を使った自動トランザクションを調査しました。

「1.」では配備や設計ことなどあまり意識する必要はありませんでしたが、「2.」はcom+として動作する仕様であることから、配備(com+への登録作業)など結構メンドウでしす。しかし、自力トランザクションで何とかしようと思う場合を考えると、安全に実装できます。また慣れてしまえば、パターン化できます。今回複数の開発ベンダで作業するため、おのおのAPIを出し合ったりします。そういう場合このような技術が必須ですね

「2.」の方法では、クラスのアトリビュートに、トランザクション及びIsolation Levelの設定を行います。そのため、クラスの属性になるため設計に注意が必要です。同じクラス内であるメソッドはREAD UNCOMMITTEDあるメソッドではSERIALIZABLEな場合など、どうせならIsolation Levelの設定でやったほうがカッコいいんですけど面倒なんですよね。まぁSQLのヒントでも対応可能なんですけどね。