在 C# 属性中构建字典
Building dictionary in C# attribute
我想在属性中构建字典。
我知道在 C# 属性中使用 AllowMultiple
,但这会导致属性被调用并且(在我的例子中,因为它是一个过滤器)触发了两次。
本质上,我想要这种行为:
[MyAttribute("someKey", "value1", "value2", "value3")]
[MyAttribute("someOtherKey", "value1", "value2", "value3")]
在 MyAttribute
中生成 Dictionary<string, HashSet<string>>
。但是,由于显而易见的原因,这不起作用,因为每一行都实例化了一个全新的 MyAttribute
.
有什么好的解决办法吗?属性是否完全支持这一点,或者我是否需要想出一些厚颜无耻的方式将参数传递到一个单一的属性声明中?
编辑:我应该注意...这是用于授权过滤器。它应该可以为多个潜在值授权多个环境(密钥)。但是,我不能使用该属性的多个实例,因为那样会多次触发过滤器。
这是一种将复杂信息插入属性的方法,使用与 System.ComponentModel.TypeConverterAttribute 相同的模式:通过将复杂性隐藏在类型中,并使用 typeof(MyType) 作为编译时常数属性.
public class MyAttributeAttribute : AuthorizeAttribute
{
public MyAttributeAttribute(Type t) : base()
{
if (!typeof(MyAbstractDictionary).IsAssignableFrom(t))
{
// ruh roh; wrong type, so bail
return;
}
// could also confirm parameterless constructor exists before using Activator.CreateInstance(Type)
Dictionary<string, HashSet<string>> dictionary = ((MyAbstractDictionary)Activator.CreateInstance(t)).GetDictionary();
this.Roles = "Fill Roles by using values from dictionary";
// fill any other properties from the dictionary
}
}
public abstract class MyAbstractDictionary
{
public abstract Dictionary<string, HashSet<string>> GetDictionary();
}
public class MyDictionary : MyAbstractDictionary
{
public MyDictionary() { } // gotta have a parameterless constructor; add it here in case we actually make another constructor
public override Dictionary<string, HashSet<string>> GetDictionary()
{
Dictionary<string, HashSet<string>> dict = new Dictionary<string, HashSet<string>>();
// build dictionary however you like
return dict;
}
}
使用抽象 class,因此您可以创建 return 不同词典的不同类型。
和用法:
[MyAttribute(typeof(MyDictionary))]
public class ClassToAttribute { }
然后您可以使用不同的字典继续制作 class MyDictionary2
,并将其用作 typeof() 来归因于其他事物。您现在还可以使用运行时信息 (!) 来构建字典,而不仅仅是硬编码值。
我想在属性中构建字典。
我知道在 C# 属性中使用 AllowMultiple
,但这会导致属性被调用并且(在我的例子中,因为它是一个过滤器)触发了两次。
本质上,我想要这种行为:
[MyAttribute("someKey", "value1", "value2", "value3")]
[MyAttribute("someOtherKey", "value1", "value2", "value3")]
在 MyAttribute
中生成 Dictionary<string, HashSet<string>>
。但是,由于显而易见的原因,这不起作用,因为每一行都实例化了一个全新的 MyAttribute
.
有什么好的解决办法吗?属性是否完全支持这一点,或者我是否需要想出一些厚颜无耻的方式将参数传递到一个单一的属性声明中?
编辑:我应该注意...这是用于授权过滤器。它应该可以为多个潜在值授权多个环境(密钥)。但是,我不能使用该属性的多个实例,因为那样会多次触发过滤器。
这是一种将复杂信息插入属性的方法,使用与 System.ComponentModel.TypeConverterAttribute 相同的模式:通过将复杂性隐藏在类型中,并使用 typeof(MyType) 作为编译时常数属性.
public class MyAttributeAttribute : AuthorizeAttribute
{
public MyAttributeAttribute(Type t) : base()
{
if (!typeof(MyAbstractDictionary).IsAssignableFrom(t))
{
// ruh roh; wrong type, so bail
return;
}
// could also confirm parameterless constructor exists before using Activator.CreateInstance(Type)
Dictionary<string, HashSet<string>> dictionary = ((MyAbstractDictionary)Activator.CreateInstance(t)).GetDictionary();
this.Roles = "Fill Roles by using values from dictionary";
// fill any other properties from the dictionary
}
}
public abstract class MyAbstractDictionary
{
public abstract Dictionary<string, HashSet<string>> GetDictionary();
}
public class MyDictionary : MyAbstractDictionary
{
public MyDictionary() { } // gotta have a parameterless constructor; add it here in case we actually make another constructor
public override Dictionary<string, HashSet<string>> GetDictionary()
{
Dictionary<string, HashSet<string>> dict = new Dictionary<string, HashSet<string>>();
// build dictionary however you like
return dict;
}
}
使用抽象 class,因此您可以创建 return 不同词典的不同类型。
和用法:
[MyAttribute(typeof(MyDictionary))]
public class ClassToAttribute { }
然后您可以使用不同的字典继续制作 class MyDictionary2
,并将其用作 typeof() 来归因于其他事物。您现在还可以使用运行时信息 (!) 来构建字典,而不仅仅是硬编码值。