在我的自定义属性的静态构造函数中,我在加载的程序集中搜索用我的属性修饰的所有类,并对它们执行一些操作。
我希望在运行时尽快调用静态构造函数,最好是在执行之前static void Main()
入口点。
目前,只有在我对属性进行一些调用后才会调用它。我could在我的程序中的其他地方进行这样的调用,但理想情况下该属性的功能应该是独立的。
为了寻找答案,我阅读了这篇文章MSDN http://msdn.microsoft.com/en-us/library/k9x6w0hc%28VS.80%29.aspx:
用户无法控制静态构造函数何时在程序中执行。
但肯定有一些棘手、狡猾或恶作剧的解决方法可以让静态构造函数尽快被调用。也许可以使用属性、反射或其他类型的魔法。能做到吗?
因为人们无疑会告诉我,没有充分的理由去做我所要求的事情,所以我提出了我的目的和我的代码:我正在尝试使用属性来声明性地配置db4o http://en.wikipedia.org/wiki/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);
}
}
}
Update:
我最终使用了带有静态方法的抽象属性。通过这种方式,我可以派生任意数量的属性,并且通过调用此方法将它们全部应用于指定的配置。
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");