我想使用属性为具有相同行为的类添加静态构造函数行为(在我的示例中为静态字段占位符替换)。
实际上我是使用一个实用程序类显式调用静态构造函数,该实用程序类使用Reflection执行静态stuf:
public class Util
{
public static void perform(System.Type container)
{
// do the static stuff (basically initializing readonly fields
}
}
public class AClass
{
static AClass()
{
Util.perform(typeof(AClass));
}
private static readonly string A = "eza";
private static readonly string B = "$A.dat";
}
我想以这种方式使用Utility类:
[StaticVerbatimPlaceholderSubstitution]
public class A
{
private static readonly string A = "eza";
private static readonly string B = "$A.dat";
}
实际上我知道如何扩展Attribute类。困扰我的是如何在合适的时间拨打电话。实际上在代码期间(在main或controller中)使用它听起来不像静态构造函数(在类的任何实例化之前)。
如果任何人可以帮助我并告诉将属性的消费代码放在哪里,我会非常高兴。
如果可以使用相同的实用程序代码(也是完成部分),那么包含引用就足以提供行为,而无需在客户端代码上进行代码调整。
谢谢,
使用代码进行编辑以进行理解:
using System;
using System.Reflection;
using System.Collections;
using System.Text.RegularExpressions;
namespace Utils
{
/// <summary>
/// Classe utilitaire pour initialiser les champs de chaines de caractères statiques en lecture seuls.
/// Cette classe, permet de faire de la substitution de chaine de caractère en utilisant les expressions :
/// ${...} qui sont remplacer sur place (verbatim) dans la chaine appelante.
/// Si des autoréférences sont présentes, le code lève une exception TypeInitializationException lors l'appel à la classe.
/// </summary>
public class VerbatimPlaceHolder
{
public static void ReplaceAll(System.Type container)
{
Hashtable computed = new Hashtable();
Hashtable visited = new Hashtable();
FieldInfo[] fields = container.GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
foreach (FieldInfo field in fields)
{
Replace(container, field, visited, computed);
}
}
private static void Replace(System.Type container, FieldInfo field, Hashtable visited, Hashtable computed)
{
if (computed.ContainsKey(field.Name)) return;
if (visited.ContainsKey(field.Name))
{
string names = "";
foreach (string name in visited.Keys) names += (names.Length > 0 ? ", " : "") + name;
throw new Exception("[ERREUR FATALE] autoréférence dans la définition des champs statiques {" + names + "} de la classe " + container.Name);
}
if (field != null && field.IsStatic && field.IsInitOnly && field.FieldType == typeof(string))
{
visited.Add(field.Name, field);
string result = (string) field.GetValue(null);
Regex placeHolderPattern = new Regex(@"\$\{([_a-zA-Z0-9]*)\}");
foreach (Match sub in placeHolderPattern.Matches(result))
{
FieldInfo node = container.GetField(sub.Groups[1].Value, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
if (node == null)
{
throw new Exception("[ERREUR FATALE] le champ statique " + sub.Value + " n'est pas défini pour " + container.Name + "." + field.Name);
}
Replace(container, node, visited, computed);
result = result.Replace(sub.Value, (string) node.GetValue(null));
}
//removing space and line breaks
Regex blanks = new Regex(@"[\s\r\n]+");
result = blanks.Replace(result, " ");
field.SetValue(null, result);
computed.Add(field.Name, field);
visited.Remove(field.Name);
}
}
}
}
答案 0 :(得分:0)
好的,我想我需要用IL注入来寻找模块初始化器(根据Mono Cecile或Postsharp)。
在Web上下文中存在允许这种行为的IAssemblyPosProcessor,但这只是Web上下文,我想让库也以批处理模式工作。