Microsoft has launched a new 44-part series called Python for Beginners on YouTube, consisting of three- to four-minute lessons from two self-described geeks at Microsoft who love programming and teaching.
عیب یابی سایت های ASP.NET5 در IIS
جزئیاتی درباره تغییرات NET Core 2.0.
It has only been about a year since .NET Core 1.0 RC came out. We are now getting close to .NET Core 2.0. We have been playing with .NET Core since the betas and feel like the quality of the 1.0 runtime was very good. Our only complaint has really been odd Visual Studio behavior. We would expect that with 2.0, the adoption of .NET Core is likely to skyrocket.
مدتی پیش نیاز پیدا کردم تا فراخوانی متدهایی را Serialize کرده و در مواقعی خاص، آن متدها را فراخوانی کنم که نتیجهی آن را در زیر با هم میبینیم.
در نظر بگیرید متدی داریم به شکل زیر:
public class EmailSender { public void Send(string emailAddress) { Console.WriteLine($"an email was sent to {emailAddress}"); } }
و میخواهیم نحوه فراخوانی این متد را Serialize کرده
new EmailSender().Send("eng.younos1986@gmail.com")
یعنی با چنین کدی، متد مورد نظر را Serialize کرده، Type ، Method.Name و Argument های آن را بدست آورده و در دیتابیس ذخیره کنیم:
Serialize(() => new EmailSender().Send("eng.younos1986@gmail.com"));
public void Serialize(Expression<Action> methodCall) { var callExpression = methodCall.Body as MethodCallExpression; var rawArguments = new object[callExpression.Arguments.Count]; var i = 0; foreach (var argg in callExpression.Arguments) { rawArguments[i++] = Expression.Lambda(Expression.Convert(argg, argg.Type)).Compile().DynamicInvoke(); } string typeName = string.Empty; var serializedArgumentsObject = rawArguments.ObjectToByteArray(); //todo: save this to db as method parameters [Binary field] if (callExpression.Object != null) //todo: save this to db as class name to be instanciated later {nvarchar field} typeName = callExpression.Object.Type.ToString(); // instance methods else typeName = callExpression.Method.ReflectedType.ToString(); // static methods var methodname = callExpression.Method.Name; //todo: save this to db as method name to be called via reflection [nvarchar field] var deserializedArgumentsObject = serializedArgumentsObject.ByteArrayToObject(); //todo: retrieve serializedObject fro db and deserialize var objInstance = GetInstance(typeName); //todo: retrieve typeName fro db and deserialize if (objInstance != null) { objInstance.GetType().GetMethod(methodname).Invoke(objInstance, (object[])deserializedArgumentsObject); } }
برای اینکه بتوانیم نحوه فراخوانی متد را به صورت Lambda Expressions به متد Serialize بفرستیم، باید نوع پارارمتر آن از جنس <Expression<Action باشد.
بعد با Cast کردن methodCall.Body به MethodCallExpression میتوانیم آرگیومنتها، نام متد و Type آن را بدست بیاوریم:
در خطوط 5 تا 10 کد بالا، آرایهای به طول تعداد Argument ها ساخته و هر Argument را به نوع خودش تبدیل کرده و درون آرایه میریزیم.
var rawArguments = new object[callExpression.Arguments.Count];
var i = 0; foreach (var argg in callExpression.Arguments) { rawArguments[i++] = Expression.Lambda(Expression.Convert(argg, argg.Type)).Compile().DynamicInvoke(); }
و با این کد
Expression.Lambda(Expression.Convert(argg, argg.Type)).Compile().DynamicInvoke();
هر آرگیومنت را به نوع خودش تبدیل کرده سپس Lambdaی آن را ساخته و کامپایل کرده تا Expression Tree به delegate تبدیل شده ( به کد معادل IL تبدیل شده)، سپس آن را با متد DynamicInvoke اجرا کرده تا دقیقا معادل آرگیومنت ارسالی را بدست آورده و در آرایه ذخیره میکنیم. در آخر آرایه بدست آمده را به بایت تبدیل کرده و میتوان در یک منبع داده دائمی ذخیره کرد.
با کد زیر، Typeی که متد، درون آن قرار دارد را بدست میآوریم:
if (callExpression.Object != null) typeName = callExpression.Object.Type.ToString(); else typeName = callExpression.Method.ReflectedType.ToString();
و همچنین نام متد:
var methodname = callExpression.Method.Name;
تا به اینجای کار Type، نام متد و آرگیومنتهای Serialize شده آن بدست آمدند که میتوان آنها را در دیتابیس ذخیره کرد. سپس استخراج، DeSerialize و فراخوانی کرد:
نحوه فراخوانی:
var methodname = callExpression.Method.Name; var deserializedArgumentsObject = serializedArgumentsObject.ByteArrayToObject(); var objInstance = GetInstance(typeName); if (objInstance != null) { objInstance.GetType().GetMethod(methodname).Invoke(objInstance, (object[])deserializedArgumentsObject); }
و برای instance ساختن از Type مورد نظر از کد زیر استفاده میکنیم:
public object GetInstance(string strFullyQualifiedName) { Type type = Type.GetType(strFullyQualifiedName); if (type != null) return Activator.CreateInstance(type); foreach (var asm in AppDomain.CurrentDomain.GetAssemblies()) { type = asm.GetType(strFullyQualifiedName); if (type != null) return Activator.CreateInstance(type); } return null; }
موارد استفاده: نوشتن نرم افزارهایی برای مدیریت یک سری Job
کد کامل MethodCallSerialization.rar
Windows Package Manager will support every Windows 10 version since the Fall Creators Update (1709)! The Windows Package Manager will be delivered with the Desktop App Installer when we ship version 1.0. If you are building software to run on Windows 10 you will have a simple way for your customers to install your software on billions of machines.