动态代理
namespace DynamicProxy
{
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
/// <summary>
/// 方法拦截器接口
/// </summary>
public interface IMethodInterceptor
{
/// <summary>
/// 调用拦截器
/// </summary>
/// <param name="targetMethod">拦截的目标方法</param>
/// <param name="args">拦截的目标方法参数列表</param>
/// <returns>拦截的目标方法返回值</returns>
object Interceptor(MethodInfo targetMethod, object[] args);
}
/// <summary>
/// 代理类生成器
/// </summary>
public class ProxyFactory : DispatchProxy
{
private IMethodInterceptor _interceptor;
/// <summary>
/// 创建代理类实例
/// </summary>
/// <param name="targetType">要代理的接口</param>
/// <param name="interceptor">拦截器</param>
/// <returns></returns>
public static object CreateInstance(Type targetType, IMethodInterceptor interceptor)
{
object proxy = GetProxy(targetType);
((ProxyFactory)proxy).GetInterceptor(interceptor);
return proxy;
}
/// <summary>
/// 创建代理类实例
/// </summary>
/// <param name="targetType">要代理的接口</param>
/// <param name="interceptorType">拦截器</param>
/// <param name="parameters">拦截器构造函数参数值</param>
/// <returns>代理实例</returns>
public static object CreateInstance(Type targetType, Type interceptorType, params object[] parameters)
{
object proxy = GetProxy(targetType);
((ProxyFactory)proxy).GetInterceptor(interceptorType, parameters);
return proxy;
}
/// <summary>
/// 创建代理类实例
/// </summary>
/// <typeparam name="TTarget">要代理的接口</typeparam>
/// <typeparam name="TInterceptor">拦截器</typeparam>
/// <param name="parameters">拦截器构造函数参数值</param>
/// <returns></returns>
public static TTarget CreateInstance<TTarget, TInterceptor>(params object[] parameters) where TInterceptor : IMethodInterceptor
{
object proxy = GetProxy(typeof(TTarget));
((ProxyFactory)proxy).GetInterceptor(typeof(TInterceptor), parameters);
return (TTarget)proxy;
}
/// <summary>
/// 获取代理类
/// </summary>
/// <param name="targetType"></param>
/// <returns></returns>
private static object GetProxy(Type targetType)
{
MethodCallExpression callexp = Expression.Call(typeof(DispatchProxy), nameof(DispatchProxy.Create), new[] { targetType, typeof(ProxyFactory) });
return Expression.Lambda<Func<object>>(callexp).Compile()();
}
/// <summary>
/// 获取拦截器
/// </summary>
/// <param name="interceptorType"></param>
/// <param name="parameters"></param>
private void GetInterceptor(Type interceptorType, object[] parameters)
{
Type[] ctorParams = parameters.Select(x => x.GetType()).ToArray();
IEnumerable<ConstantExpression> paramsExp = parameters.Select(x => Expression.Constant(x));
NewExpression newExp = Expression.New(interceptorType.GetConstructor(ctorParams), paramsExp);
this._interceptor = Expression.Lambda<Func<IMethodInterceptor>>(newExp).Compile()();
}
/// <summary>
/// 获取拦截器
/// </summary>
/// <param name="interceptor"></param>
private void GetInterceptor(IMethodInterceptor interceptor)
{
this._interceptor = interceptor;
}
/// <summary>
/// 执行代理方法
/// </summary>
/// <param name="targetMethod"></param>
/// <param name="args"></param>
/// <returns></returns>
protected override object Invoke(MethodInfo targetMethod, object[] args)
{
return this._interceptor.Interceptor(targetMethod, args);
}
}
/// <summary>
/// 表演者
/// </summary>
public interface IPerform
{
/// <summary>
/// 唱歌
/// </summary>
void Sing();
/// <summary>
/// 跳舞
/// </summary>
void Dance();
}
/// <summary>
/// 具体的表演者——刘德华 Andy
/// </summary>
public class AndyPerformer : IPerform
{
public void Dance()
{
System.Console.WriteLine("给大家表演一个舞蹈");
}
public void Sing()
{
System.Console.WriteLine("给大家唱首歌");
}
}
/// <summary>
/// 经纪人——负责演员的所有活动
/// </summary>
public class PerformAgent : IMethodInterceptor
{
public IPerform _perform;
public PerformAgent(IPerform perform)
{
this._perform = perform;
}
public object Interceptor(MethodInfo targetMethod, object[] args)
{
System.Console.WriteLine("各位大佬,要我们家艺人演出清闲联系我");
object result = targetMethod.Invoke(this._perform, args);
System.Console.WriteLine("各位大佬,表演结束该付钱了");
return result;
}
}
public class Program
{
static void Main(string[] args)
{
IPerform perform;
//perform = ProxyFactory.CreateInstance<IPerform, PerformAgent>(new AndyPerformer());
//perform.Sing();
//perform.Dance();
ServiceCollection serviceDescriptors = new ServiceCollection();
serviceDescriptors.AddSingleton<IPerform>(ProxyFactory.CreateInstance<IPerform, PerformAgent>(new AndyPerformer()));
IServiceProvider serviceProvider = serviceDescriptors.BuildServiceProvider();
perform = serviceProvider.GetService<IPerform>();
perform.Sing();
perform.Dance();
System.Console.ReadKey();
}
}
}










