我已经实现了一个属性类,看起来像:
internal class DataExchangeItem : Attribute
{
public DataExchangeItem(string request)
{
Request = request;
}
public string Request { get; set; }
}
现在我有几个类使用这个属性,如:
[DataExchangeItem("DownloadDataRequest")]
internal class DownloadDataRequestHandler : IDataHandler
{ ... }
那么我有一个类,它有一个静态方法,看起来像
public static Class RequestHandlerCreator
{
public static IDataHandler CreateDataHandler(string request)
{
switch(request){... // compare strings and give DataHandler}
}
}
现在我正试图用一个语句取代开关语句,在那里我可以检查所有类的属性,然后在属性-请求-属性中获得我搜索的请求字符串的类。
要获得定义了我的属性的所有Type
的列表,我使用:
List<Type> customAttributes = (from type in Assembly.GetExecutingAssembly().GetTypes()
where type.GetCustomAttributes(typeof(DataExchangeItem),true).Length > 0
where type.GetCustomAttributesData().Count > 0
select type).ToList();
我知道我可以在Type
- Object
上调用type.GetCustomAttributesData()
以获得CustomAttributeData
的列表。每个CustomAttributeData
-Property than都有一个NamedArguments集合。
不幸的是,我没有设法得到Type
-对象为我的搜索字符串。
我的问题是:
如何在我的自定义属性所在的程序集中获得类型定义并且请求属性具有我搜索的值?
谢谢荷兰人。你的代码可以工作。我在linq语句中完全转换了它:
private static Type FindTypeForRequest(string request)
{
return (from module in Assembly.GetExecutingAssembly().Modules
where module.GetTypes().Length > 0
from type in module.GetTypes()
where type.CustomAttributes.Any()
let customAttribute = type.CustomAttributes.SingleOrDefault(a => a.AttributeType == typeof (DataExchangeItem))
where customAttribute != null
where customAttribute.ConstructorArguments.Any(argument => argument.Value.ToString() == request)
select type).FirstOrDefault();
}
好的,我是这样做的:
public Type CreateDataHandler(string requestName)
{
Assembly _assembly = Assembly.GetExecutingAssembly();
foreach (Module _module in _assembly.Modules)
{
if (_module.GetTypes().Length > 0)
{
foreach(Type _type in _module.GetTypes())
{
if (_type.CustomAttributes.Count() > 0)
{
CustomAttributeData _customAttribute = _type.CustomAttributes.SingleOrDefault(a => a.AttributeType == typeof(DataExchangeItem));
if (_customAttribute != null)
{
foreach (var _argument in _customAttribute.ConstructorArguments)
{
if (_argument.Value.ToString() == requestName)
{
return _type;
}
}
}
}
}
}
}
return null;
}