ComponentResourceManager#ApplyResources

WindowsFormsアプリケーションのデザインでForm(Form1)を生成し、コントロールを配置した状態でFormのLocalizableプロパティをtrueに設定するとForm1.Designer.csの初期化コードは以下のように変化する。

例) Labelコントロールが一つだけ配置されているForm1クラスの初期化コード(コメントは削除)

  • Form1#Localizable=false
private void InitializeComponent()
{
    this.label1 = new System.Windows.Forms.Label();
    this.SuspendLayout();

    this.label1.AutoSize = true;
    this.label1.Location = new System.Drawing.Point(13, 13);
    this.label1.Name = "label1";
    this.label1.Size = new System.Drawing.Size(35, 12);
    this.label1.TabIndex = 0;
    this.label1.Text = "label1";

    this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
    this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
    this.ClientSize = new System.Drawing.Size(108, 43);
    this.Controls.Add(this.label1);
    this.Name = "Form1";
    this.Text = "Form1";
    this.ResumeLayout(false);
    this.PerformLayout();
}
  • Form1#Localizable=true
{
    System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));
    this.label1 = new System.Windows.Forms.Label();
    this.SuspendLayout();

    resources.ApplyResources(this.label1, "label1");
    this.label1.Name = "label1";

    resources.ApplyResources(this, "$this");
    this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
    this.Controls.Add(this.label1);
    this.Name = "Form1";
    this.ResumeLayout(false);
    this.PerformLayout();
}

Localizable=falseの際にハードコードされていたプロパティの値はこの場合Form1.resxに分離され、実行時にComponentResourceManagerによりプロパティ値を注入される。このリソースファイルをコピーしてカルチャに合わせたリソースを作って同一ディレクトリに放り込んで置くだけでFormとコントロールのローカライズが出来てしまう。なんて素晴らしいんだ。

.NETアプリケーションとVisual Studio 2005における素晴らしくスマートなローカリゼーションの仕組みだが、どこかで見たことがある。そう、これは国(地域)情報、言語情報という依存性を外部から解決するためのDI(Dependency Injection)そのものではないのか。

この仕組み、WindowsFormでは見た所Formのデザイナ部分でしか使われていないようだが、もっと色々な所で使い道があると思うのだがどうなのだろう。(まあ普通のResourceManagerも充分に便利だが)