从程序集到方法和属性的调用
原文地址:https://www.cnblogs.com/siyi/p/5009032.html
//动态加载程序集
Assembly ass = Assembly.LoadFile(@"F:\Cheng_20140819\VS2012_WorkSpace\Assembly\Assembly\TestClassLibary\bin\Debug\TestClassLibary.dll");
//利用GetTypes获取所有类型 public internal 都能拿到
Type[] ts = ass.GetTypes();
foreach (Type item in ts)
{
Console.WriteLine(item.Name);
}
//只获取公开的类型
//获取导出的类型
Type[] publicTypes = ass.GetExportedTypes();
foreach (Type item in publicTypes)
{
Console.WriteLine("--->>"+item.Name);
}
//获取特定的Type,类型需要完全限定名称 : 记得带上命名空间哟~
Type personType = ass.GetType("TestClassLibary.Person");
//根据特定的Type 来创建对象,无参数构造函数
object personObj = Activator.CreateInstance(personType);
//获取特定的方法
MethodInfo method = personType.GetMethod("Add");
//调用,参数1 代表获取的类型的对象 ,参数2 代表调用的方法的参数列表
object obj= method.Invoke(personObj, new object[] { 2, 3 });
//获取参数的类型
ParameterInfo[] args = methodInfo.GetParameters();
Args[0].ParameterType
//获取继承接口的类型
Type[] types = type.GetInterfaces()
//方法设置泛型
methodInfo.MakeGenericMethod(type);
//--------------------------------调用属性---------------------
Assembly ass = Assembly.LoadFile (@"F:\Cheng_20140819\VS2012_WorkSpace\Assembly\Assembly\TestClassLibary\bin\Debug\TestClassLibary.dll");
Type t = ass.GetType ("TestClassLibary.Person");
object obj = Activator.CreateInstance (t);
PropertyInfo pifo = t.GetProperty ("Name");
pifo.SetValue (obj, "cheng");
MethodInfo mifo = t.GetMethod ("WriteName");
mifo.Invoke (obj, null);
//--------------------------------利用特定的构造函数
Assembly ass = Assembly.LoadFile (@"F:\Cheng_20140819\VS2012_WorkSpace\20151129_Heima_Day11_Assembly\Assembly\TestClassLibary\bin\Debug\TestClassLibary.dll");
Type personType = ass.GetType ("TestClassLibary.Person");
//这里使用 ctor GetConstructor() 其参数列表就 是指定的构造函数的列表
ConstructorInfo ctor = personType.GetConstructor (new Type[] { typeof (string), typeof (int), typeof (string) });
object o = ctor.Invoke (new object[] { "ccc", 20, "CCC@sina.cn" });
Console.WriteLine (o.ToString ());
MethodInfo mInfo = personType.GetMethod ("WriteName");
mInfo.Invoke (o, null);
反射实例带参数的特性类
特性
public abstract class BaseValidationAttribute: Attribute
{
public BaseValidationAttribute(string errorMessage) {
ErrorMessage = errorMessage;
}
public string ErrorMessage { get; set; }
public abstract bool IsValid();
}
public class RoleAuthAttribute : BaseValidationAttribute
{
private List<string> _Role = new List<string>();
public RoleAuthAttribute(object[] role) : base("授权错误") {
foreach (var item in role) {
_Role.Add(item.ToString());
}
}
public RoleAuthAttribute(object[] role, string error) : base(error) {
foreach (var item in role)
{
_Role.Add(item.ToString());
}
}
public override bool IsValid()
{
IPrincipal principal = GenerateAndGetPrincipal.GetPrincipal();
if (principal == null)
{
return false;
}
foreach (var item in _Role) {
if (principal.IsInRole(item) == true)
return true;
}
return false;
}
}
验证
public static bool Validate(Type type,out string errorMessage)
{
errorMessage = null;
foreach (var item in type.CustomAttributes)
{
//获取构造函数信息
ConstructorInfo service = item.Constructor;
if (service.DeclaringType.IsSubclassOf(typeof(BaseValidationAttribute)))
{
List<object> paramList = new List<object>();
//获取构造函数实参信息
foreach(var parameterInfoItem in item.ConstructorArguments) {
List<object> list = new List<object>();
foreach (var parameterItem in (ReadOnlyCollection<CustomAttributeTypedArgument>) parameterInfoItem.Value) {
//添加实参值
list.Add(parameterItem.Value);
}
paramList.Add(list.ToArray());
}
//调用构造方法生成特性实例
BaseValidationAttribute validationAttribute = service.Invoke(paramList.ToArray()) as BaseValidationAttribute;
//调用特性的方法进行验证
bool isSuccess = validationAttribute.IsValid();
if (isSuccess == false)
{
errorMessage = validationAttribute.ErrorMessage;
return false;
}
}
}
return true;
}
反射搜索标记 BindingFlags
例:查找当前类的方法公共方法,不包括父类
var type = typeof(ClassA);
var methods = type.GetMembers(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.DeclaredOnly);
BindingFlags.Instance和BindingFlags.Static二者必须有一项或者都有
BindingFlags枚举值:
BindingFlags.IgnoreCase:表示忽略 name 的大小写,不应考虑成员名的大小写
BindingFlags.DeclaredOnly:只应考虑在所提供类型的层次结构级别上声明的成员。不考虑继承成员。
BindingFlags.Instance:只搜索实例成员
BindingFlags.Static:只搜索静态成员
BindingFlags.Public:只搜索公共成员
BindingFlags.NonPublic:只搜索非公共成员
BindingFlags.FlattenHierarchy:应返回层次结构上的公共静态成员和受保护的静态成员。不返回继承类中的私有静态成员。静态成员包括字段、方法、事件和属性。不返回嵌套类型。
BindingFlags.InvokeMethod:表示调用方法,而不调用构造函数或类型初始值设定项。对 SetField 或 SetProperty 无效。
BindingFlags.CreateInstance:表示调用构造函数。忽略 name。对其他调用标志无效。
BindingFlags.GetField:表示获取字段值。
BindingFlags.SetField:表示设置字段值。
BindingFlags.GetProperty:表示获取属性。
BindingFlags.SetProperty:表示设置属性。