代码如下:
/// <summary>
/// 声明委托
/// </summary>
/// <param name="serviceProvider"></param>
/// <returns></returns>
public delegate object
ServiceObjFactory(IServiceProvider serviceProvider);
/// <summary>
/// 自定义类型注入特性类
/// </summary>
public class CustomServiceFilterAttribute : Attribute, IFilterFactory
{
/// <summary>
/// 声明私有委托变量,用于首次赋值,后续直接从委托中获取无需重复实例
/// </summary>
private ServiceObjFactory _objFactory;
/// <summary>
/// 传递的实现类特性
/// </summary>
private readonly Type _implementationType;
public CustomServiceFilterAttribute(Type implementationType)
{
_implementationType = implementationType;
}
public bool IsReusable { get; set; }
public IFilterMetadata CreateInstance(IServiceProvider serviceProvider)
{
if (serviceProvider == null)
{
throw new ArgumentNullException("serviceProvider");
}
if (_implementationType == null)
{
throw new ArgumentNullException("_implementationType");
}
#region 使用表达式目录树实现
if (_objFactory == null)
{
var providerExp = Expression.Parameter(typeof(IServiceProvider), "proveider");
var ctors = _implementationType.GetTypeInfo().DeclaredConstructors;
var lastCtor = ctors.OrderByDescending(m => m.GetParameters().Length).First();
var parameters = lastCtor.GetParameters();
List<Expression> exps = new List<Expression>();
if (parameters.Length > 0)
{
foreach (var parameter in parameters)
{
var parameterType = parameter.ParameterType;
var constantExp = Expression.Constant(parameterType, typeof(Type));
var methodInfo = typeof(IServiceProvider).GetMethod("GetService");
var methodCallExp = Expression.Call(providerExp, methodInfo, constantExp);
var convertExp = Expression.Convert(methodCallExp, parameterType);
exps.Add(convertExp);
}
}
var newExp = Expression.New(lastCtor, exps.ToArray());
var lambdaExp = Expression.Lambda<Func<IServiceProvider, object>>(newExp, providerExp);
_objFactory = lambdaExp.Compile().Invoke;
}
return (IFilterMetadata)_objFactory(serviceProvider);
#endregion
#region 使用反射的方式
//var objArray = new List<object>();
//var constructors = _implementationType.GetTypeInfo().DeclaredConstructors;
//ConstructorInfo lastConstructor = null;
//if (constructors?.Count() > 0)
//{
// lastConstructor = constructors
// .OrderByDescending(m => m.GetParameters().Length).First();
//}
//var typeParameters = lastConstructor.GetParameters();
//if (typeParameters != null)
//{
// foreach (var parameterInfo in typeParameters)
// {
// var serviceType = serviceProvider.GetService(parameterInfo.ParameterType);
// objArray.Add(serviceType);
// }
//}
//return (IFilterMetadata)Activator.CreateInstance(_implementationType, objArray.ToArray());
#endregion
}
}
//调用方式
[CustomServiceFilter(typeof(CustomExceptionAttribute))]
public IActionResult Index()
{
return View();
}