プロパティインジェクションのためのアノテーション位置を拡張する
日記でも何度か紹介しているが、Seasar2と同様のプロパティインジェクションで用いるアノテーション(カスタム属性)の宣言は、拙作の.NET用DIコンテナでも同様に、以下のように記述する。
public class HatenaUser
{
[Binding(BindingType = BindingType.MUST, Value = "Kazzz")]
public virtual string HandleName
{
get { return this.handleName; }
set { this.handleName= value; }
}
}
そして、カスタム属性BindingAttributeクラスの定義は以下のようになっている。
[AttributeUsage(AttributeTargets.Property, Inherited = true, AllowMultiple = false)] public class BindingAttribute : Attribute { 〜 }
つまり、プロパティの定義位置にアノテーション(面倒なので今後、アノテーションで統一する)を記述するのが決まりになる訳だ。このことは、派生クラスを作る際にアノテーションを再設定するためには、例え処理のオーバライドが不要であっても、以下のようにオーバライドの記述(橙色の部分)が強制されることを意味する。(そのために、プロパティ"HandleName"には前もってvirtualキーワードをつけている)
public class DelivedHatenaUser : HatenaUser { [Binding(BindingType = BindingType.MUST, Value = "Kazzz2")] public override string HandleName { get { return base.HandleName; } set { base.HandleName= value; } } }
これではコード量を少なくするのが目的の一つだったはずのアノテーションが、逆にコードを増やしてしまう。Visual Studio 2005の場合、Intellisenseからoverrideを書くと上記のコードは自動的に生成されるが、そもそも不要なコードがあること自体気持ちが悪い。
そこで、カスタム属性BindingAttributeクラスを拡張してプロパティインジェクションのアノテーションを型に対しても宣言できるようにしてみた。
- 新たなBindingAttributeクラスの宣言と、追加されたプロパティ
[AttributeUsage(AttributeTargets.Class| AttributeTargets.Property , Inherited = true, AllowMultiple = true)]
public class BindingAttribute : Attribute
{
private string property;
〜
public string Property
{
get { return this.property; }
set { this.property = value; }
}
〜
}
この新しいBindingAttributeにより、DelivedHatenaUserクラスにおける、プロパティインジェクションのためのアノテーションは、以下のように記述できるようになる。カスタム属性の使用属性であるAttributeUsageに"AttributeTargets.Class"が追加され、"AllowMultiple = true"により複数個のアノテーション定義が許可されるようになる。
- プロパティインジェクションのためのアノテーションをクラス位置で宣言する例
[Binding(Property = "HandleName",Value = "Kazzz2")] [Binding(Property = "MailAddress", Value = "Kazzz2@hogehoge.net.jp")] [Binding(Property = "Phone", Value = "8165865854655")] public class DelivedHatenaUser : HatenaUser { }
これでオーバライドのために発生していた、不要なコードを除去できるようになる。もちろん、従来どおりの宣言方法はそのまま有効なので、本当にオーバライドが必要な場合は元々の宣言方法を用いればよい。