DynamicCallMethodExpressionTreeInvokerHelper CodeDom 动态编译代码 执行代码


namespace Test
{
    using System;
    using Microsoft.CSharp;
    using System.CodeDom.Compiler;
    using System.Reflection;
    using Microshaoft;
    public class ContextInfo
    {
        public string F1;
    }
    class Program
    {
        static void Main(string[] args)
        {
            string codeSnippet1 = @"
Console.WriteLine(x);
Console.WriteLine(y.F1);
//TResult r;
return true;
";
            string codeSnippet2 = @"
Console.WriteLine(x);
Console.WriteLine(y.F1);
Console.WriteLine(z);
//TResult r;
//return true;
";
            string codeSnippet3 = @"
//Console.WriteLine(x);
//Console.WriteLine(y.F1);
Console.WriteLine(""Action()"");
//TResult r;
//return true;
";
            SourceCodeDynamicCompilerInvokers invokers = new SourceCodeDynamicCompilerInvokers();
            invokers
                .Add
                    (
                        new string[] { "System.dll", @"Noname3.exe" }
                        , new string[] { "System", "System", "Test" }
                        , "Func<string, ContextInfo, bool>"
                        , "Call"
                        , new string[] { "x", "y" }
                        , codeSnippet1
                    );
            invokers
                .Add
                    (
                        new string[] { "System.dll", "System.dll", @"Noname3.exe" }
                        , new string[] { "System", "System.Text", "Test" }
                        , "Action<int, ContextInfo, bool>"
                        , "Call2"
                        , new string[] { "x", "y", "z" }
                        , codeSnippet2
                    );
            invokers
                .Add
                    (
                        new string[] { "System.dll", "System.dll", @"Noname3.exe" }
                        , new string[] { "System", "System.Text", "Test" }
                        , "Action"
                        , "Call3"
                        , null //new string[] { "x", "y", "z" }
                        , codeSnippet3
                    );
            invokers.Build();
            //Func<string, ContextInfo, bool> func = (Func<string, ContextInfo, bool>) cr["Call"];
            dynamic func = invokers["Call"];
            var r = func("xxxx", new ContextInfo() { F1 = "FF1" });
            Console.WriteLine(r);
            //Action<int, ContextInfo, bool> action = (Action<int, ContextInfo, bool>) cr["Call2"];
            dynamic action = invokers["Call2"];
            action(999, new ContextInfo() { F1 = "FFF1" }, false);
            //Action action = (Action) cr["Call3"];
            dynamic action2 = invokers["Call3"];
            action2();
            Console.ReadLine();
        }
    }
}
namespace Microshaoft
{
    using System;
    using System.CodeDom.Compiler;
    using System.Collections.Concurrent;
    using System.Linq;
    using System.Reflection;
    using System.Text;
    public class SourceCodeDynamicCompilerInvokers
    {
        private string _codeTemplate = @"
namespace Microshaoft.Temp
{{
    {0}
    public static partial class InvokersManager
    {{
        public static
                        {1}                        //方法签名定义,如: Func<string, string, bool>
                        {2}                        //方法名称
                            ()
        {{
            var invoker = new {1}                //方法签名定义,如: Func<string, string, bool>
                                (
                                    (
                                        {3}        //参数列表
                                    ) =>
                                    {{
                                        {4}        //代码
                                    }}
                                );
            return invoker;
        }}
    }}
}}
";
        private class CodeTemplatePlaceHolder
        {
            public string[] ReferencedAssemblies;
            public string[] UsingsTargets;
            public string MethodDefinitionStatment;
            public string MethodName;
            public string[] MethodArgs;
            public string EmbedInlineCodeSnippet;
            public Delegate MethodInvoker;
        }
        public Delegate this[string key]
        {
            get
            {
                return
                    _sourceCodes[key].MethodInvoker;
            }
        }
        private ConcurrentDictionary<string, CodeTemplatePlaceHolder> _sourceCodes
                        = new ConcurrentDictionary<string, CodeTemplatePlaceHolder>();
        private void Compile
                    (
                        string[] referencedAssemblies
                        , string sourceCode
                    )
        {
            CodeDomProvider codeDomProvider = CodeDomProvider.CreateProvider("CSharp");
            var compilerParameters = new CompilerParameters();
            Array
                .ForEach
                    (
                        referencedAssemblies
                        , (x) =>
                        {
                            compilerParameters
                                .ReferencedAssemblies
                                .Add(x);
                        }
                    );
            compilerParameters.GenerateExecutable = false;
            compilerParameters.GenerateInMemory = true;
            //Console.WriteLine(code);
            var compilerResults = codeDomProvider
                                        .CompileAssemblyFromSource
                                            (
                                                compilerParameters
                                                , sourceCode
                                            );
            var assembly = compilerResults.CompiledAssembly;
            var codes = _sourceCodes.AsEnumerable();
            var stringBuilder = new StringBuilder();
            foreach (var kvp in codes)
            {
                MethodInfo mi = assembly
                                    .GetType("Microshaoft.Temp.InvokersManager")
                                    .GetMethod(kvp.Key);
                Delegate invoker = (Delegate) mi.Invoke(null, null);
                kvp.Value.MethodInvoker = invoker;
            }
        }
        public void Add
                        (
                            string[] referencedAssemblies
                            , string[] usingsTargets
                            , string methodSignatureDefinition
                            , string methodName
                            , string[] methodArgs
                            , string embedInlineCodeSnippet
                        )
        {
            _sourceCodes
                .TryAdd
                    (
                            methodName
                            , new CodeTemplatePlaceHolder()
                                {
                                    ReferencedAssemblies = referencedAssemblies
                                     ,
                                    UsingsTargets = usingsTargets
                                     ,
                                    MethodDefinitionStatment = methodSignatureDefinition
                                     ,
                                    MethodName = methodName
                                     ,
                                    MethodArgs = methodArgs
                                     ,
                                    EmbedInlineCodeSnippet = embedInlineCodeSnippet
                                }
                    );
        }
        public void Build()
        {
            string[] referencedAssemblies
                        = _sourceCodes
                            .SelectMany
                                (
                                    (x) =>
                                    {
                                        return
                                            x
                                                .Value
                                                .ReferencedAssemblies;
                                    }
                                ).Distinct()
                                 .ToArray();
            var sourceCodes = _sourceCodes.AsEnumerable();
            var stringBuilder = new StringBuilder();
            foreach (var kvp in sourceCodes)
            {
                var usingStatement = "using {0};";
                var usingsTargets = kvp
                                        .Value
                                        .UsingsTargets
                                        .Distinct();
                var usingsStatementsItems
                            = usingsTargets
                                .Select
                                    (
                                        (xx) =>
                                        {
                                            var rr = string.Format(usingStatement, xx);
                                            return rr;
                                        }
                                    );
                var usingsStatements = string.Join("\r\n", usingsStatementsItems);
                var methodArgs = kvp
                                    .Value
                                    .MethodArgs;
                var methodArgsStatement = string.Empty;
                if
                    (
                        methodArgs != null
                        &&
                        methodArgs.Length > 0
                    )
                {
                    methodArgsStatement = string.Join(", ", methodArgs);
                }
                var sourceCode = string
                                    .Format
                                        (
                                            _codeTemplate
                                            , usingsStatements
                                            , kvp.Value.MethodDefinitionStatment
                                            , kvp.Value.MethodName
                                            , methodArgsStatement
                                            , kvp.Value.EmbedInlineCodeSnippet
                                        );
                stringBuilder
                    .AppendLine(sourceCode);
            }
            Compile(referencedAssemblies, stringBuilder.ToString());
        }
    }
}


namespace ConsoleApplication
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Net.Mail;
    using System.Net.Mime;
    using Microshaoft;
    public class Class1
    {
        static void Main(string[] args)
        {
            Console.WriteLine("生成 eml 文件");
            string html = "<html><body><a href=\"http://www.live.com\"><img src=\"cid:attachment1\"></a>";
            html += "<script src=\"cid:attachment2\"></script>中国字";
            html += "<a href=\"http://www.google.com\"><br><img src=\"cid:attachment1\"></a><script>alert('mail body xss')<script></body></html>";
            AlternateView view = AlternateView.CreateAlternateViewFromString(html, null, MediaTypeNames.Text.Html);
            //LinkedResource picture = new LinkedResource(@"pic.JPG", MediaTypeNames.Image.Jpeg);
            //picture.ContentId = "attachment1";
            //view.LinkedResources.Add(picture);
            //LinkedResource script = new LinkedResource(@"a.js", MediaTypeNames.Text.Plain);
            //script.ContentId = "attachment2";
            //view.LinkedResources.Add(script);
            MailMessage mail = new MailMessage();
            mail.AlternateViews.Add(view);
            mail.From = new MailAddress("test@microshaoft.com", "<script>alert('mail from xss')</script>");
            mail.To.Add(new MailAddress("microshaoft@gmail.com", "<script>alert('mail to xss')</script>"));
            mail.To.Add(new MailAddress("microshaoft@qq.com", "<script>alert('mail to xss')</script>"));
            mail.Subject = "<script>alert('mail subject xss')</script>" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
            byte[] buffer = mail.GetBytes();
            File.WriteAllBytes(@"d:\temp.eml", buffer);
            Console.WriteLine("====================================================================");
            Console.ReadLine();
            Console.WriteLine("计算表达式");
            string formula = "(({0}-{1})/{2}+{3})*{4}";
            string result = JScriptEvaluator.ComputeFormula<double>
                                                    (
                                                        formula
                                                        , 1f
                                                        , 2.1
                                                        , 3.1
                                                        , 4.0
                                                        , 5.0
                                                    );
            Console.WriteLine(result);
            double x;
            x = DataTableColumnExpression.ComputeFormula<double, double>
                                                    (
                                                        formula
                                                        , 1f
                                                        , 2.1
                                                        , 3.1
                                                        , 4.0
                                                        , 5.0
                                                    );
            Console.WriteLine(x);
            //=================================================================================================
            formula = "IIF(1=2, F1, F2) + ((--F1) * F2) + F3";
            var tuples = new Tuple<string, double>[]
                                            {
                                                Tuple.Create<string,double>("F1", 1.0)
                                                , Tuple.Create<string,double>("F2", 2.0)
                                                , Tuple.Create<string,double>("F3", 3.0)
                                                , Tuple.Create<string,double>("F4", 4.0)
                                                , Tuple.Create<string,double>("F3", 2.0)
                                            };
            x = DataTableColumnExpression.ComputeFormula<double, double>(formula, tuples);
            Console.WriteLine(x);
            Console.ReadLine();
        }
    }
}
namespace Microshaoft
{
    using System;
    using System.CodeDom.Compiler;
    using System.Collections.Generic;
    using System.Data;
    using System.Linq;
    using System.Reflection;
    public class DataTableColumnExpression
    {
        private static MethodInfo _mi = typeof(string).GetMethods().First
                                                                    (
                                                                        m => m.Name.Equals("Format")
                                                                        && m.GetParameters().Length == 2
                                                                        && m.IsStatic
                                                                        && m.GetParameters()[1].Name == "args"
                                                                    );
        private class ObjectEqualityComparer<T> : IEqualityComparer<T>
        {
            private Func<T, T, bool> _onEqualsProcessFunc;
            private Func<T, int> _onGetHashCodeProcessFunc;
            public ObjectEqualityComparer
                        (
                            Func<T, T, bool> onEqualsProcessFunc
                            , Func<T, int> onGetHashCodeProcessFunc
                        )
            {
                _onEqualsProcessFunc = onEqualsProcessFunc;
                _onGetHashCodeProcessFunc = onGetHashCodeProcessFunc;
            }
            public bool Equals(T x, T y)
            {
                if (Object.ReferenceEquals(x, y))
                {
                    return true;
                }
                if (Object.ReferenceEquals(x, null) || Object.ReferenceEquals(y, null))
                {
                    return false;
                }
                return _onEqualsProcessFunc(x, y);
            }
            public int GetHashCode(T x)
            {
                if (Object.ReferenceEquals(x, null))
                {
                    return 0;
                }
                return _onGetHashCodeProcessFunc(x);
            }
        }
        public static TResult ComputeFormula<TResult, TParameter>
                                                    (
                                                        string formula
                                                        , params TParameter[] parameters
                                                    )
        {
            var dt = new DataTable();
            var list = parameters.ToList();
            var parametersNames = new List<string>(); ;
            int i = 0;
            Array.ForEach
                    (
                        parameters
                        , (x) =>
                        {
                            string f = string.Format("F{0}", i++);
                            parametersNames.Add(f);
                            var dc = new DataColumn(f, typeof(TParameter));
                            dt.Columns.Add(dc);
                        }
                    );
            string expression = string.Format(formula, parametersNames.ToArray());
            dt.Columns.Add(new DataColumn("Microshaoft", typeof(TResult), expression));
            var dr = dt.NewRow();
            i = 0;
            Array.ForEach
            (
                parameters
                , (x) =>
                {
                    dr[i++] = x;
                }
            );
            dt.Rows.Add(dr);
            return (TResult)dr["Microshaoft"];
        }
        public static TResult ComputeFormula<TResult, TParameter>
                                                    (
                                                        string formula
                                                        , params Tuple<string, TParameter>[] parameters
                                                    )
        {
            var dt = new DataTable();
            var comparer = new ObjectEqualityComparer<Tuple<string, TParameter>>
                                            (
                                                (x, y) =>
                                                {
                                                    return x.Item1 == y.Item1;
                                                }
                                                , (x) =>
                                                {
                                                    return x.Item1.GetHashCode();
                                                }
                                            );
            var list = parameters.Distinct
                                    (
                                        comparer
                                    )
                                    .ToList();
            list.ForEach
                    (
                        (x) =>
                        {
                            var dc = new DataColumn
                                            (
                                                x.Item1
                                                , x.Item2.GetType()
                                            );
                            dt.Columns.Add(dc);
                        }
                    );
            dt.Columns.Add(new DataColumn("Microshaoft", typeof(TResult), formula));
            var dr = dt.NewRow();
            list.ForEach
                    (
                        (x) =>
                        {
                            dr[x.Item1] = x.Item2;
                        }
                    );
            dt.Rows.Add(dr);
            return (TResult)dr["Microshaoft"];
        }
    }
    public class JScriptEvaluator
    {
        private static MethodInfo _mi = typeof(string).GetMethods().First
                                                                        (
                                                                            m => m.Name.Equals("Format")
                                                                            && m.GetParameters().Length == 2
                                                                            && m.IsStatic
                                                                            && m.GetParameters()[1].Name == "args"
                                                                        );
        private static Func<string, object[], object> _func = null;
        public static string ComputeFormula<TParameter>(string formula, params TParameter[] parameters)
        {
            object[] objects = new object[parameters.Length];
            Array.Copy(parameters, objects, objects.Length);
            string expression1 = string.Format(formula, objects);
            return (string)JScriptEvaluator.Eval(expression1);
            //=====================================================================
            object[] ps = new object[parameters.Length];
            Array.Copy(parameters, 0, ps, 0, ps.Length);
            if (_func == null)
            {
                _func = DynamicCallMethodExpressionTreeInvokerHelper.CreateMethodCallInvokerFunc<string, string>
                                                (
                                                    typeof(string)
                                                    , () =>
                                                    {
                                                        var methodsInfos = typeof(string).GetMethods();
                                                        var methodInfo = methodsInfos.First
                                                                                        (
                                                                                            (x) =>
                                                                                            {
                                                                                                var parametersInfos = x.GetParameters();
                                                                                                //Debug.Assert(x.Name.ToLower() == "Format".ToLower());
                                                                                                return
                                                                                                    x.Name.ToLower() == "Format".ToLower()
                                                                                                    && x.IsStatic
                                                                                                    && parametersInfos[0].ParameterType == typeof(string)
                                                                                                    && parametersInfos[1].ParameterType == typeof(object[])
                                                                                                    && Attribute.IsDefined
                                                                                                                    (
                                                                                                                        parametersInfos[1]
                                                                                                                        , typeof(ParamArrayAttribute)
                                                                                                                    );
                                                                                            }
                                                                                        );
                                                        return methodInfo;
                                                    }
                                                );
            }
            string expression = (string)_mi.Invoke
                                                (
                                                    null
                                                    , new object[]
                                                            {
                                                                formula
                                                                , ps
                                                            }
                                                );
            expression = (string) _func
                                    (
                                        formula
                                        , new object[]
                                                    {
                                                        formula
                                                        , ps
                                                    }
                                    );
            return (string) JScriptEvaluator.Eval(expression);
        }
        public static object Eval(string statement)
        {
            return _evaluatorType.InvokeMember
                                        (
                                            "Eval"
                                            , BindingFlags.InvokeMethod
                                            , null
                                            , _evaluator
                                            , new object[]
                                                    {
                                                        statement
                                                    }
                                        );
        }
        static JScriptEvaluator()
        {
            CodeDomProvider provider = CodeDomProvider.CreateProvider("JScript");
            CompilerParameters parameters;
            parameters = new CompilerParameters();
            parameters.GenerateInMemory = true;
            CompilerResults results;
            results = provider.CompileAssemblyFromSource(parameters, _JScript);
            Assembly assembly = results.CompiledAssembly;
            _evaluatorType = assembly.GetType("Microshaoft.JScriptEvaluator");
            var constructorInfo = _evaluatorType.GetConstructors().First();
            var func = DynamicCallMethodExpressionTreeInvokerHelper.CreateNewInstanceConstructorInvokerFunc
                                                            (
                                                                _evaluatorType
                                                                , constructorInfo
                                                            );
            _evaluator = func(null);
            //_evaluator = Activator.CreateInstance(_evaluatorType);
        }
        private static object _evaluator = null;
        private static Type _evaluatorType = null;
        /// <summary>
        /// JScript代码
        /// </summary>
        private static readonly string _JScript =
            @"
                package Microshaoft
                {
                    class JScriptEvaluator
                    {
                        public function Eval(statement : String) : String
                        {
                            return eval(statement);
                        }
                    }
                }
            ";
    }
}
namespace Microshaoft
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Linq.Expressions;
    using System.Reflection;
    public static class DynamicCallMethodExpressionTreeInvokerHelper
    {
        public static Func<object[], object> CreateNewInstanceConstructorInvokerFunc
                                                        (
                                                            Type type
                                                            , Func<ConstructorInfo> getConstructorInfoFunc
                                                        )
        {
            var constructorInfo = getConstructorInfoFunc();
            return CreateNewInstanceConstructorInvokerFunc<object>
                                                        (
                                                            type
                                                            , constructorInfo
                                                        );
        }
        public static Func<object[], T> CreateNewInstanceConstructorInvokerFunc<T>
                                                        (
                                                            Type type
                                                            , Func<ConstructorInfo> getConstructorInfoFunc
                                                        )
        {
            var constructorInfo = getConstructorInfoFunc();
            return CreateNewInstanceConstructorInvokerFunc<T>
                                                        (
                                                            type
                                                            , constructorInfo
                                                        );
        }
        public static Func<object[], object> CreateNewInstanceConstructorInvokerFunc
                                                        (
                                                            Type type
                                                            , ConstructorInfo constructorInfo
                                                        )
        {
            return CreateNewInstanceConstructorInvokerFunc<object>(type, constructorInfo);
        }
        public static Func<object[], T> CreateNewInstanceConstructorInvokerFunc<T>
                                                        (
                                                            Type type
                                                            , ConstructorInfo constructorInfo
                                                        )
        {
            var parametersInfos = constructorInfo.GetParameters();
            var constructorParametersExpressions = new List<ParameterExpression>();
            int i = 0;
            Array.ForEach
                    (
                        parametersInfos
                        , (x) =>
                        {
                            var parameterExpression = Expression.Parameter
                                                                    (
                                                                        x.ParameterType
                                                                        , "p" + i.ToString()
                                                                    );
                            constructorParametersExpressions.Add(parameterExpression);
                            i++;
                        }
                    );
            var newExpression = Expression.New(constructorInfo, constructorParametersExpressions);
            var inner = Expression.Lambda(newExpression, constructorParametersExpressions);
            var args = Expression.Parameter(typeof(object[]), "args");
            var body = Expression.Invoke
                                    (
                                        inner
                                        , constructorParametersExpressions.Select
                                                                    (
                                                                        (p, ii) =>
                                                                        {
                                                                            return Expression.Convert
                                                                                            (
                                                                                                Expression.ArrayIndex
                                                                                                                (
                                                                                                                    args
                                                                                                                    , Expression.Constant(ii)
                                                                                                                )
                                                                                                , p.Type
                                                                                            );
                                                                        }
                                                                    ).ToArray()
                                    );
            var outer = Expression.Lambda<Func<object[], T>>(body, args);
            var func = outer.Compile();
            return func;
        }
        public static Action<T, object[]> CreateMethodCallInvokerAction<T>
                                                            (
                                                                Type type
                                                                , Func<MethodInfo> getMethodInfoFunc
                                                            )
        {
            var methodInfo = getMethodInfoFunc();
            return CreateMethodCallInvokerAction<T>
                                                (
                                                    type
                                                    , methodInfo
                                                );
        }
        public static Action<T, object[]> CreateMethodCallInvokerAction<T>
                                                            (
                                                                Type type
                                                                , MethodInfo methodInfo
                                                            )
        {
            ParameterExpression instanceParameterExpression;
            MethodCallExpression methodCallExpression;
            ParameterExpression argumentsParameterExpression = GetMethodArgumentsParameterExpression
                                    (
                                        type
                                        , methodInfo
                                        , out instanceParameterExpression
                                        , out methodCallExpression
                                    );
            var lambda = Expression.Lambda<Action<T, object[]>>(methodCallExpression, instanceParameterExpression, argumentsParameterExpression);
            var action = lambda.Compile();
            return action;
        }
        public static Func<T, object[], TResult> CreateMethodCallInvokerFunc<T, TResult>
                                                            (
                                                                Type type
                                                                , Func<MethodInfo> getMethodInfoFunc
                                                            )
        {
            var methodInfo = getMethodInfoFunc();
            return
                CreateMethodCallInvokerFunc<T, TResult>
                                                    (
                                                        type
                                                        , methodInfo
                                                    );
        }
        public static Func<T, object[], TResult> CreateMethodCallInvokerFunc<T, TResult>
                                                            (
                                                                Type type
                                                                , MethodInfo methodInfo
                                                            )
        {
            ParameterExpression instanceParameterExpression;
            MethodCallExpression methodCallExpression;
            ParameterExpression argumentsParameterExpression = GetMethodArgumentsParameterExpression
                                    (
                                        type
                                        , methodInfo
                                        , out instanceParameterExpression
                                        , out methodCallExpression
                                    );
            var lambda = Expression.Lambda<Func<T, object[], TResult>>(methodCallExpression, instanceParameterExpression, argumentsParameterExpression);
            var func = lambda.Compile();
            return func;
        }
        private static ParameterExpression GetMethodArgumentsParameterExpression
                                            (
                                                Type type
                                                , MethodInfo methodInfo
                                                , out ParameterExpression instanceParameterExpression
                                                , out MethodCallExpression methodCallExpression
                                            )
        {
            var argumentsParameterExpression = Expression.Parameter(typeof(object[]), "args");
            instanceParameterExpression = Expression.Parameter(type);
            UnaryExpression instanceConvertUnaryExpression = null;
            if (!methodInfo.IsStatic)
            {
                instanceConvertUnaryExpression = Expression.Convert(instanceParameterExpression, type);
            }
            var parametersParameterExpressionList = new List<Expression>();
            int i = 0;
            var parametersInfos = methodInfo.GetParameters();
            Array.ForEach
                    (
                        parametersInfos
                        , (x) =>
                        {
                            BinaryExpression valueObject = Expression.ArrayIndex
                                                                        (
                                                                            argumentsParameterExpression
                                                                            , Expression.Constant(i)
                                                                        );
                            UnaryExpression valueCast = Expression.Convert
                                                                        (
                                                                            valueObject
                                                                            , x.ParameterType
                                                                        );
                            parametersParameterExpressionList.Add(valueCast);
                            i++;
                        }
                    );
            methodCallExpression = Expression.Call(instanceConvertUnaryExpression, methodInfo, parametersParameterExpressionList);
            return argumentsParameterExpression;
        }
    }
}
namespace Microshaoft
{
    using System;
    using System.IO;
    using System.Net.Mail;
    using System.Reflection;
    public static partial class ExtensionMethodsManager
    {
        public static byte[] GetBytes(this MailMessage mailMessage)
        {
            Assembly assembly = typeof(SmtpClient).Assembly;
            Type type = assembly.GetType("System.Net.Mail.MailWriter");
            var parametersTypes = new[]
                                    { 
                                        typeof(Stream)
                                    };
            object x = null;
            using (Stream stream = new MemoryStream())
            {
                var constructorInfo = type.GetConstructor
                                                    (
                                                        BindingFlags.Instance | BindingFlags.NonPublic
                                                        , null
                                                        , parametersTypes
                                                        , null
                                                    );
                var func = DynamicCallMethodExpressionTreeInvokerHelper.CreateNewInstanceConstructorInvokerFunc<object>
                                                        (
                                                            type
                                                            , constructorInfo
                                                        );
                x = func(new[] { stream });
                var action = DynamicCallMethodExpressionTreeInvokerHelper.CreateMethodCallInvokerAction<MailMessage>
                                                        (
                                                            typeof(MailMessage)
                                                            , () =>
                                                            {
                                                                var methodInfo = typeof(MailMessage).GetMethod
                                                                                        (
                                                                                            "Send"
                                                                                            , BindingFlags.NonPublic | BindingFlags.Instance
                                                                                            , null
                                                                                            , new[] { type, typeof(bool) }
                                                                                            , null
                                                                                        );
                                                                return methodInfo;
                                                            }
                                                        );
                action
                    (
                        mailMessage
                        , new[]
                            {
                                x
                                , true
                            }
                    );
                byte[] buffer = StreamDataHelper.ReadDataToBytes(stream);
                return buffer;
            }
        }
    }
}
namespace Microshaoft
{
    using System.IO;
    public static class StreamDataHelper
    {
        public static byte[] ReadDataToBytes(Stream stream)
        {
            byte[] buffer = new byte[64 * 1024];
            MemoryStream ms = new MemoryStream();
            int r = 0;
            int l = 0;
            long position = -1;
            if (stream.CanSeek)
            {
                position = stream.Position;
                stream.Position = 0;
            }
            while (true)
            {
                r = stream.Read(buffer, 0, buffer.Length);
                if (r > 0)
                {
                    l += r;
                    ms.Write(buffer, 0, r);
                }
                else
                {
                    break;
                }
            }
            byte[] bytes = new byte[l];
            ms.Position = 0;
            ms.Read(bytes, 0, (int)l);
            ms.Close();
            ms.Dispose();
            ms = null;
            if (position >= 0)
            {
                stream.Position = position;
            }
            return bytes;
        }
    }
}

原文地址:https://www.cnblogs.com/Microshaoft/p/2635636.html