如几个相关问题所示(例如,将 Class 实例作为参数传递给 Attribute constructor 中的 Lambda expression in attribute constructor)仅允许编译时文字作为属性的参数。
我确实想到了一种可能有效也可能无效的解决方法。这个想法是创建一个从正则表达式属性派生的自定义属性类,并在构造上执行正则表达式查找并将结果传递给它的基。
免责声明:我还没有实际测试过它(也不打算这样做;-)。
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false)]
public class PostalCodeAttribute : RegularExpressionAttribute
{
private static ConcurrentDictionary<string, Func<string, string>> _resolverDict = new ConcurrentDictionary<string, Func<string, string>>();
private static string Resolve(string source)
{
Func<string, string> resolver = null;
if (!_resolverDict.TryGetValue(source, out resolver))
throw new InvalidOperationException(string.Format("No resolver for {0}", source));
return resolver(source);
}
public static void RegisterResolver(string source, Func<string, string> resolver)
{
_resolverDict.AddOrUpdate(source, resolver, (s, c) => resolver);
}
static PostalCodeAttribute()
{
// necessary to enable client side validation
DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(PostalCodeAttribute), typeof(RegularExpressionAttributeAdapter));
}
public PostalCodeAttribute(string patternSource)
: base(Resolve(patternSource))
{
}
}
/// ...
public void SomeIntializer()
{
PostalCodeAttribute.RegisterResolver("db_source", (s) => PostalCodeRegularExpressions.LookupFromDatabase());
}
public class SomeClassWithDataValidation
{
[PostalCode("db_source")]
public string PostalCode { get; set; }
}
请注意,这仅适用于在实例化任何这些属性之前完成匹配解析器函数的注册。