カスタム属性の静的コンストラクターで、ロードされたアセンブリから属性で装飾されたすべてのクラスを検索し、それらに対して何らかのアクションを実行します。
静的コンストラクターは、実行時にできるだけ早く、できればstatic void Main()
エントリ ポイントの実行前に呼び出されるようにしたいと考えています。
現在、属性を呼び出した後にのみ呼び出されます。プログラムの他の場所でそのような呼び出しを行うこともできますが、理想的には、属性の機能は自己完結型です。
答えを探して、MSDNでこれを読みました:
ユーザーは、静的コンストラクターがプログラムで実行されるタイミングを制御できません。
しかし、確実に、静的コンストラクターを ASAP と呼ぶには、トリッキーで、狡猾で、いたずらな回避策があります。おそらく、属性、反射、またはその他の種類の魔法を使用できます。それはできますか?
人々は間違いなく、私が要求したことを行う正当な理由はないと言うので、目的とコードを示します。属性を使用して、db4oファクトリを宣言的に構成しようとしています。接続を確立した後で属性の静的コンストラクターが呼び出された場合、それは効果がなく、役に立ちません。したがって、私のプログラムがそのような接続を確立する機会を得る前に、それを呼び出す必要があります。
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
sealed public class CascadeOnUpdateAttribute : Attribute
{
public bool Flag { get; private set; }
public CascadeOnUpdateAttribute() : this(true) { }
public CascadeOnUpdateAttribute(bool flag)
{
Flag = flag;
}
static CascadeOnUpdateAttribute()
{
var targets = from assembly in AppDomain.CurrentDomain.GetAssemblies()
from type in assembly.GetTypes()
from attribute in type.GetCustomAttributes(typeof(CascadeOnUpdateAttribute), false).Cast<CascadeOnUpdateAttribute>()
select new { Type = type, Cascade = attribute.Flag };
foreach (var target in targets)
{
Db4oFactory.Configure().ObjectClass(target.Type).CascadeOnUpdate(target.Cascade);
}
}
}
アップデート:
静的メソッドで抽象属性を使用することになりました。このようにして、好きなだけ属性を派生させることができ、この 1 つのメソッドを呼び出すことで、指定された構成にすべての属性が適用されます。
public abstract class Db4oAttribute : Attribute
{
public abstract void Configure(IConfiguration config, Type type);
public static void ApplyAttributes(IConfiguration config)
{
var targets = from assembly in AppDomain.CurrentDomain.GetAssemblies()
from type in assembly.GetTypes()
from attribute in type.GetCustomAttributes(typeof(Db4oAttribute), false).Cast<Db4oAttribute>()
select new { Type = type, Attribute = attribute };
foreach (var target in targets)
{
target.Attribute.Configure(config, target.Type);
}
}
}
そして呼び出しサイト:
Db4oAttribute.ApplyAttributes(Db4oFactory.Configure());
_db = Db4oFactory.OpenFile("Test.db4o");