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