لینک مستقیم بسته کامل
لینک دوم
dotnet new worker
<Project Sdk="Microsoft.NET.Sdk.Worker"> <PropertyGroup> <TargetFramework>netcoreapp3.0</TargetFramework> <UserSecretsId>dotnet-MyWorkerServiceApp-B76DB08E-FFBB-4AD1-89B5-93BF483D1BD0</UserSecretsId> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.Extensions.Hosting" Version="3.0.0-preview8.19405.4" /> </ItemGroup> </Project>
namespace MyWorkerServiceApp { public class Program { public static void Main(string[] args) { CreateHostBuilder(args).Build().Run(); } public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureServices((hostContext, services) => { services.AddHostedService<Worker>(); }); } }
public class Worker : BackgroundService { private readonly ILogger<Worker> _logger; public Worker(ILogger<Worker> logger) { _logger = logger; } protected override async Task ExecuteAsync(CancellationToken stoppingToken) { while (!stoppingToken.IsCancellationRequested) { _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now); await Task.Delay(1000, stoppingToken); } } }
public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .UseWindowsService() .ConfigureServices((hostContext, services) => { //services.AddHttpClient(); services.AddHostedService<Worker>(); });
cs create WorkerServiceDemo binPath=C:\Path\To\WorkerServiceDemo.exe
public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .UseSystemd() .ConfigureServices((hostContext, services) => { services.AddHostedService<Worker>(); });
System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35
برای استفاده از این تکنولوژی ابتدا نیاز است تا یک جفتکلید عمومی/خصوصی (توسط ادمین، منبع گواهینامهها، یک بانک یا یک ابزار خاص) فراهم شود تا از آن برای اینکریپشن استفاده شود. سپس دادههای موردنظر (هر داده کلی که قصد ارسال و توزیع آن را داریم مثل یک اسمبلی) با استفاده از یک الگوریتم هشکردن (مثل MD5، SHA یا ترکیبی از آنها، هرچند MD5 توصیه نمیشود) پردازش شده و یک هشکد مخصوص تولید میشود. این هشکد با استفاده از کلید خصوصی دردسترس اینکریپت میشود و به عنوان یک امضای دیجیتال به همراه داده موردنظر ارسال یا توزیع میشود. در سمت مصرف کننده که با استفاده از یک روش خاص و امن به کلید عمومی دسترسی پیدا کرده است عملیات دیکریپت کردن این امضای دیجیتال با استفاده از کلید عمومی انجام شده و هشکد مربوطه بدست میآید. همچنین عملیات تولید هشکد با استفاده از دادهها در سمت مصرف کننده انجام شده و هشکد دادهها نیز دوباره با استفاده از همان الگوریتم استفاده شده در سمت توزیعکننده تولید میشود. سپس این دو مقدار محاسبه شده در سمت مصرفکننده با یکدیگر مقایسه شده و درصورت برابر بودن میتوان اطمینان حاصل کرد همان دادهای که توزیع کننده در اصل ارسال کرده بدون تغییر به دست مصرف کننده رسیده است. درواقع ویژگی اینکریپت/دیکریپت کردن دادهها توسط جفتکلید این است که بهصورت یکطرفه بوده و دادههای اینکریپت شده با استفاده از یک کلید خصوصی را تنها با استفاده از کلید عمومی همان کلید خصوصی میتوان بدرستی دیکریپت کرد.
1. تولید و مدیریت جفتکلیدهای قوی- نامگذاریشده (Strongly Named Key Pairs)
همانطور که در قسمت قبل اشاره شد برای نامگذاری قوی یک اسمبلی به یک کلید عمومی (public key) و یک کلید خصوصی (private key) که در مجموع به آن یک جفت کلید (key pair) میگویند، نیاز است.برای اینکار میتوان با استفاده از برنامه sn.exe (عنوان کامل آن Microsoft .Net Framework Strong Name Utility است) یک جفت کلید تولید کرده و آن را در یک فایل و یا در CSP (یا همان cryptographic service provider) ذخیره کرد. همچنین اینکار را میتوان توسط ویژوال استودیو نیز انجام داد. امکان موردنظر در فرم پراپرتی یک پروژه و در تب Signing آن وجود دارد.
نکته: یک CSP عنصری از API کریپتوگرافی ویندوز (Win32 CryptoAPI) است که سرویسهایی چون اینکریپشن، دیکریپشن، و تولید امضای دیجیتال را فراهم میکند. این پرووایدرها همچنین تسهیلاتی برای مخازن کلیدها فراهم میکنند که از اینکریپشنهای قوی و ساختار امنیتی سیستم عامل (سیستم امنیتی و دسترسی کاربران ویندوز) برای محافظت از تمام کلیدهای کریپتوگرافی ذخیره شده در مخزن استفاده میکند. بهطور خلاصه و مفید میشود اشاره کرد که میتوان کلیدهای کریپتوگرافی را درون یک مخزن کلید CSP ذخیره کرد و تقریبا مطمئن بود که تا زمانیکه هیچکس کلمه عبور سیستم عامل را نداند، این کلیدها امن خواهند ماند. برای کسب اطلاعات بیشتر به دادههای CryptoAPI در اسناد SDK سیستم عامل خود مراجعه کنید.
برنامه sn به همراه SDKهای ویندوز نصب میشود. البته با نصب ویژوال استودیو تمام SDKهای موردنیاز مطابق با نسخههای موجود، نصب خواهد شد. مسیر نسخه 4 و 32 بیتی این برنامه در سیستم عامل Windows 7 بهصورت زیر است:
C:\Program Files\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\sn.exe
با استفاده از آرگومان k همانند دستور زیر یک جفتکلید جدید تولید شده و در فایل MyKeys.snk در ریشه درایو d: ذخیره میشود:
sn –k d:\MyKeys.snk
نکته: به بزرگی و کوچکی حروف سوییچهای دستورات برنامه sn دقت کنید!
این کار یک جفت کلید کریپتوگرافی 1024 بیتی بهصورت تصادفی تولید میکند. این دستور را باید در خط فرمانی (Command Prompt) اجرا نمود که مسیر فایل sn.exe را بداند. برای راحتی کار میتوان از خط فرمان ویژوال استودیو (Visual Studio Command Prompt) استفاده کرد.
نکته: اجرای عملیات فوق در یک شرکت یا قسمت توسعه یک شرکت، تنها یک بار نیاز است زیرا تمام اسمبلیهای تولیدی تا زمانیکه عناوین ساده متمایزی دارند میتوانند از یک جفت کلید مشترک استفاده کنند.
نکته: هرچند که میتوان از پسوندهای دیگری نیز برای نام فایل حاوی جفت کلید استفاده کرد، اما توصیه میشود از همین پسوند snk. استفاده شود.
فایل تولید شده حاوی هر دو کلید «عمومی» و «خصوصی» است. میتوان با استفاده از دستور زیر کلید عمومی موجود در فایل mykeys.snk را استخراج کرده و در فایل mypublickey.snk ذخیره کرد:
sn –p d:\mykeys.snk d:\mypublickey.snk
sn -tp MyPublicKey.snk
sn -i MyKeys.snk MyStrongNameKeys
sn –m n
sn –m y
sn -d MyStrongNameKeys
نکته: برای استفاده از این ویژگی در ویژوال استودیو، باید در تب Signing در تنظیمات پروژه گزینه Sign the Assembly را انتخاب کرد. سپس میتوان فایل حاوی جفت کلیدهای تولیدشده را انتخاب یا فایل جدیدی تولید کرد. البته ویژوال استودیو تا نسخه 2010 امکانی جهت استفاده از مخازن CSP را ندارد.
[assembly:AssemblyKeyFileAttribute("MyKeys.snk")]
sn –vf MyAsm.exe
Microsoft (R) .NET Framework Strong Name Utility Version 2.0.50727.42 Copyright (C) Microsoft Corporation. All rights reserved. Failed to verify assembly -- Strong name validation failed for assembly MyAsm.exe'.
sn –p d:\MyKeys.snk d:\MyPublicKey.snk sn –pc MyKeysContainer d:\MyPublicKey.snk
csc.exe /delaysign /keyfile:d:\MyPublicKey.snk /out:d:\MyAsm.exe d:\Class1.cs
al /out:<assembly name> <module name> /keyfile:<file name>
sn –Vr d:\MyAsm.exe
sn –R d:\MyAsm.exe MyKeys.snk sn –R d:\MyAsm.exe MyKeysContainer
sn –D assembly1 assembly2
sn –Vu d:\MyAsm.exe
sn –Vx
sn –Vl
C:\Program Files\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools\gacutil.exe
gacutil /i c:\MyAsm.dll
gacutil /u MyAsm
gacutil /u MyAsm,Version=1.3.0.5
gacutil /l
gacutil /l MyAsm
var ws = MSBuildWorkspace.Create(); var sln = ws.OpenSolutionAsync(@"..\..\..\Roslyn.sln").Result; // Print the root of the solution. Console.WriteLine(Path.GetFileName(sln.FilePath)); // Get dependency graph to perform a sort. var g = sln.GetProjectDependencyGraph(); var ps = g.GetTopologicallySortedProjects(); // Print all projects, their documents, and references. foreach (var p in ps) { var proj = sln.GetProject(p); Console.WriteLine("> " + proj.Name); Console.WriteLine(" > References"); foreach (var r in proj.ProjectReferences) { Console.WriteLine(" - " + sln.GetProject(r.ProjectId).Name); } foreach (var d in proj.Documents) { Console.WriteLine(" - " + d.Name); } }
Roslyn.sln > Roslyn01 > References - Program.cs - AssemblyInfo.cs - .NETFramework,Version=v4.6.AssemblyAttributes.cs
var ws = MSBuildWorkspace.Create(); var sln = ws.OpenSolutionAsync(@"..\..\..\Roslyn.sln").Result; // Get the Tests\Bar.cs document. var proj = sln.Projects.Single(p => p.Name == "Roslyn04.Tests"); var test = proj.Documents.Single(d => d.Name == "Bar.cs"); var tree = test.GetSyntaxTreeAsync().Result; var root = tree.GetRootAsync().Result; // Get all the spans in the document that are classified as language elements. var spans = Classifier.GetClassifiedSpansAsync(test, root.FullSpan).Result.ToDictionary(c => c.TextSpan.Start, c => c); // Print the source text with appropriate colorization. var txt = tree.GetText().ToString(); var i = 0; foreach (var c in txt) { var span = default(ClassifiedSpan); if (spans.TryGetValue(i, out span)) { var color = ConsoleColor.Gray; switch (span.ClassificationType) { case ClassificationTypeNames.Keyword: color = ConsoleColor.Cyan; break; case ClassificationTypeNames.StringLiteral: case ClassificationTypeNames.VerbatimStringLiteral: color = ConsoleColor.Red; break; case ClassificationTypeNames.Comment: color = ConsoleColor.Green; break; case ClassificationTypeNames.ClassName: case ClassificationTypeNames.InterfaceName: case ClassificationTypeNames.StructName: case ClassificationTypeNames.EnumName: case ClassificationTypeNames.TypeParameterName: case ClassificationTypeNames.DelegateName: color = ConsoleColor.Yellow; break; case ClassificationTypeNames.Identifier: color = ConsoleColor.DarkGray; break; } Console.ForegroundColor = color; } Console.Write(c); i++; }
var ws = MSBuildWorkspace.Create(); var sln = ws.OpenSolutionAsync(@"..\..\..\Roslyn.sln").Result; // Get the Tests\Qux.cs document. var proj = sln.Projects.Single(p => p.Name == "Roslyn04.Tests"); var qux = proj.Documents.Single(d => d.Name == "Qux.cs"); Console.WriteLine("Before:"); Console.WriteLine(); Console.WriteLine(qux.GetSyntaxTreeAsync().Result.GetText()); Console.WriteLine(); Console.WriteLine(); // Apply formatting and print the result. var res = Formatter.FormatAsync(qux).Result; Console.WriteLine("After:"); Console.WriteLine(); Console.WriteLine(res.GetSyntaxTreeAsync().Result.GetText()); Console.WriteLine();
Before: using System; namespace Roslyn04.Tests { class Qux { public void Baz() { Console.WriteLine(42); return; } } } After: using System; namespace Roslyn04.Tests { class Qux { public void Baz() { Console.WriteLine(42); return; } } }
var ws = MSBuildWorkspace.Create(); var sln = ws.OpenSolutionAsync(@"..\..\..\Roslyn.sln").Result; // Get the Tests project. var proj = sln.Projects.Single(p => p.Name == "Roslyn04.Tests"); // Locate the symbol for the Bar.Foo method and the Bar.Qux property. var comp = proj.GetCompilationAsync().Result; var barType = comp.GetTypeByMetadataName("Roslyn04.Tests.Bar"); var fooMethod = barType.GetMembers().Single(m => m.Name == "Foo"); var quxProp = barType.GetMembers().Single(m => m.Name == "Qux"); // Find callers across the solution. Console.WriteLine("Find callers of Foo"); Console.WriteLine(); var callers = SymbolFinder.FindCallersAsync(fooMethod, sln).Result; foreach (var caller in callers) { Console.WriteLine(caller.CallingSymbol); foreach (var location in caller.Locations) { Console.WriteLine(" " + location); } } Console.WriteLine(); Console.WriteLine(); // Find all references across the solution. Console.WriteLine("Find all references to Qux"); Console.WriteLine(); var references = SymbolFinder.FindReferencesAsync(quxProp, sln).Result; foreach (var reference in references) { Console.WriteLine(reference.Definition); foreach (var location in reference.Locations) { Console.WriteLine(" " + location.Location); } }
var ws = MSBuildWorkspace.Create(); var sln = ws.OpenSolutionAsync(@"..\..\..\Roslyn.sln").Result; // Get the Tests\Foo.cs document. var proj = sln.Projects.Single(p => p.Name == "Roslyn04.Tests"); var foo = proj.Documents.Single(d => d.Name == "Foo.cs"); // Find the 'dot' token in the first Console.WriteLine member access expression. var tree = foo.GetSyntaxTreeAsync().Result; var model = proj.GetCompilationAsync().Result.GetSemanticModel(tree); var consoleDot = tree.GetRoot().DescendantNodes().OfType<MemberAccessExpressionSyntax>().First().OperatorToken; // Get recommendations at the indicated cursor position. // // Console.WriteLine // ^ var res = Recommender.GetRecommendedSymbolsAtPosition( model, consoleDot.GetLocation().SourceSpan.Start + 1, ws).ToList(); foreach (var rec in res) { Console.WriteLine(rec); }
System.Console.Beep() System.Console.Beep(int, int) System.Console.Clear()
var ws = MSBuildWorkspace.Create(); var sln = ws.OpenSolutionAsync(@"..\..\..\Roslyn.sln").Result; // Get Tests\Bar.cs before making changes. var oldProj = sln.Projects.Single(p => p.Name == "Roslyn04.Tests"); var oldDoc = oldProj.Documents.Single(d => d.Name == "Bar.cs"); Console.WriteLine("Before:"); Console.WriteLine(); var oldTxt = oldDoc.GetTextAsync().Result; Console.WriteLine(oldTxt); Console.WriteLine(); Console.WriteLine(); // Get the symbol for the Bar.Foo method. var comp = oldProj.GetCompilationAsync().Result; var barType = comp.GetTypeByMetadataName("Roslyn04.Tests.Bar"); var fooMethod = barType.GetMembers().Single(m => m.Name == "Foo"); // Perform the rename. var newSln = Renamer.RenameSymbolAsync(sln, fooMethod, "Foo2", ws.Options).Result; // Get Tests\Bar.cs after making changes. var newProj = newSln.Projects.Single(p => p.Name == "Roslyn04.Tests"); var newDoc = newProj.Documents.Single(d => d.Name == "Bar.cs"); Console.WriteLine("After:"); Console.WriteLine(); var newTxt = newDoc.GetTextAsync().Result; Console.WriteLine(newTxt);
var ws = MSBuildWorkspace.Create(); var sln = ws.OpenSolutionAsync(@"..\..\..\Roslyn.sln").Result; // Get the Tests\Baz.cs document. var proj = sln.Projects.Single(p => p.Name == "Roslyn04.Tests"); var baz = proj.Documents.Single(d => d.Name == "Baz.cs"); Console.WriteLine("Before:"); Console.WriteLine(); Console.WriteLine(baz.GetSyntaxTreeAsync().Result.GetText()); Console.WriteLine(); Console.WriteLine(); var oldRoot = baz.GetSyntaxRootAsync().Result; var memberAccesses = oldRoot.DescendantNodes().OfType<CastExpressionSyntax>(); var newRoot = oldRoot.ReplaceNodes(memberAccesses, (_, m) => m.WithAdditionalAnnotations(Simplifier.Annotation)); var newDoc = baz.WithSyntaxRoot(newRoot); // Invoke the simplifier and print the result. var res = Simplifier.ReduceAsync(newDoc).Result; Console.WriteLine("After:"); Console.WriteLine(); Console.WriteLine(res.GetSyntaxTreeAsync().Result.GetText()); Console.WriteLine();
using System; using System.Reflection.Emit; namespace FastReflectionTests { class Program { static int Calculate(int a, int b, int c) { var result = a * b; return result - c; } static void Main(string[] args) { //روش متداول Console.WriteLine(Calculate(10, 2, 3)); //تعریف امضای متد var myMethod = new DynamicMethod( name: "CalculateMethod", returnType: typeof(int), parameterTypes: new[] { typeof(int), typeof(int), typeof(int) }, m: typeof(Program).Module); //تعریف بدنه متد var il = myMethod.GetILGenerator(); il.Emit(opcode: OpCodes.Ldarg_0); // بارگذاری اولین آرگومان بر روی پشته ارزیابی il.Emit(opcode: OpCodes.Ldarg_1); // بارگذاری دومین آرگومان بر روی پشته ارزیابی il.Emit(opcode: OpCodes.Mul); // انجام عملیات ضرب il.Emit(opcode: OpCodes.Stloc_0); // ذخیره سازی نتیجه عملیات ضرب در یک متغیر محلی il.Emit(opcode: OpCodes.Ldloc_0); // متغیر محلی را بر روی پشته ارزیابی قرار میدهد تا در عملیات بعدی قابل استفاده باشد il.Emit(opcode: OpCodes.Ldarg_2); // آرگومان سوم را بر روی پشته ارزیابی قرار میدهد il.Emit(opcode: OpCodes.Sub); // انجام عملیات تفریق il.Emit(opcode: OpCodes.Ret); // بازگشت نتیجه //فراخوانی متد پویا var method = (Func<int, int, int, int>)myMethod.CreateDelegate(typeof(Func<int, int, int, int>)); Console.WriteLine(method(10, 2, 3)); } } }
System.InvalidProgramException was unhandled Message=Common Language Runtime detected an invalid program.
il.DeclareLocal(typeof(int));
static int Calculate(int x) { int result = 0; for (int i = 0; i < 10; i++) { result += i * x; } return result; }
using System; using System.Reflection.Emit; namespace FastReflectionTests { class Program { static int Calculate(int x) { int result = 0; for (int i = 0; i < 10; i++) { result += i * x; } return result; } static void Main(string[] args) { //روش متداول Console.WriteLine(Calculate(10)); //تعریف امضای متد var myMethod = new DynamicMethod( name: "CalculateMethod", returnType: typeof(int), // خروجی متد عدد صحیح است parameterTypes: new[] { typeof(int) }, // یک پارامتر عدد صحیح دارد m: typeof(Program).Module); //تعریف بدنه متد var il = myMethod.GetILGenerator(); // از برچسبها برای انتقال کنترل استفاده میشود // در اینجا به دو برچسب برای تعریف ابتدای حلقه // و همچنین برای پرش به جایی که متد خاتمه مییابد نیاز داریم var loopStart = il.DefineLabel(); var methodEnd = il.DefineLabel(); // variable 0; result = 0 il.DeclareLocal(typeof(int)); // برای تعریف متغیر محلی نتیجه عملیات il.Emit(OpCodes.Ldc_I4_0); // عدد ثابت صفر را بر روی پشته ارزیابی قرار میدهد il.Emit(OpCodes.Stloc_0); // و نهایتا این عدد ثابت به متغیر محلی انتساب داده خواهد شد // variable 1; i = 0 il.DeclareLocal(typeof(int)); // در اینجا کار تعریف و مقدار دهی متغیر حلقه انجام میشود il.Emit(OpCodes.Ldc_I4_0); // عدد ثابت صفر را بر روی پشته ارزیابی قرار میدهد il.Emit(OpCodes.Stloc_1); // و نهایتا این عدد ثابت به متغیر حلقه در ایندکس یک انتساب داده خواهد شد // در اینجا کار تعریف بدنه حلقه شروع میشود il.MarkLabel(loopStart); // شروع حلقه را علامتگذاری میکنیم تا بعدا بتوانیم به این نقطه پرش نمائیم il.Emit(OpCodes.Ldloc_1); // در ادامه میخواهیم بررسی کنیم که آیا مقدار متغیر حلقه از عدد 10 کوچکتر است یا خیر il.Emit(OpCodes.Ldc_I4, 10); // عدد ثابت ده را بر روی پشته ارزیابی قرار میدهد // برای انجام بررسیهای تساوی یا کوچکتر یا بزرگتر نیاز است ابتدا دو متغیر مدنظر بر روی پشته قرار گیرند il.Emit(OpCodes.Bge, methodEnd); // اگر اینطور نیست و مقدار متغیر از 10 کمتر نیست، کنترل برنامه را به انتهای متد هدایت خواهیم کرد // i * x il.Emit(OpCodes.Ldloc_1); // مقدار متغیر حلقه را بر روی پشته قرار میدهد il.Emit(OpCodes.Ldarg_0); // مقدار اولین آرگومان متد را بر روی پشته قرار میدهد il.Emit(OpCodes.Mul); // انجام عملیات ضرب // نتیجه این عملیات اکنون بر روی پشته قرار گرفته است // result += il.Emit(OpCodes.Ldloc_0); // متغیر نتیجه را بر روی پشته قرار میدهد il.Emit(OpCodes.Add); // اکنون عملیات جمع بر روی نتیجه ضرب قسمت قبل که بر روی پشته قرار دارد و همچنین متغیر نتیجه انجام میشود il.Emit(OpCodes.Stloc_0); // ذخیره سازی نتیجه در متغیر محلی // i++ // در اینجا کار افزایش متغیر حلقه انجام میشود il.Emit(OpCodes.Ldloc_1); // مقدار متغیر حلقه بر روی پشته قرار میگیرد il.Emit(OpCodes.Ldc_I4_1); // عدد ثابت یک بر روی پشته قرار میگیرد il.Emit(OpCodes.Add); // سپس این دو عدد بارگذاری شده با هم جمع خواهند شد il.Emit(OpCodes.Stloc_1); // نتیجه در متغیر حلقه ذخیره خواهد شد // مرحله بعد شبیه سازی حلقه با پرش به ابتدای برچسب آن است il.Emit(OpCodes.Br, loopStart); //در اینجا انتهای متد علامتگذاری شده است il.MarkLabel(methodEnd); il.Emit(OpCodes.Ldloc_0); // مقدار نتیجه بر روی پشته قرار داده شده il.Emit(OpCodes.Ret); // و بازگشت داده میشود //فراخوانی متد پویا var method = (Func<int, int>)myMethod.CreateDelegate(typeof(Func<int, int>)); Console.WriteLine(method(10)); } } }
using System; using System.Reflection.Emit; namespace FastReflectionTests { class Program { public static void print(int i) { Console.WriteLine("i: {0}", i); } static void Main(string[] args) { //روش متداول print(10); //تعریف امضای متد var myMethod = new DynamicMethod( name: "myMethod", returnType: typeof(void), parameterTypes: null, // پارامتری ندارد m: typeof(Program).Module); //تعریف بدنه متد var il = myMethod.GetILGenerator(); il.Emit(OpCodes.Ldc_I4, 10); // عدد ثابت 10 را بر روی پشته قرار میدهد // اکنون این مقدار بر روی پشته است و از آن میتوان برای فراخوانی متد پرینت استفاده کرد il.Emit(OpCodes.Call, typeof(Program).GetMethod("print")); il.Emit(OpCodes.Ret); //فراخوانی متد پویا var method = (Action)myMethod.CreateDelegate(typeof(Action)); method(); } } }
using System; using System.Reflection.Emit; namespace FastReflectionTests { class Program { static void Main(string[] args) { //تعریف امضای متد var myMethod = new DynamicMethod( name: "mulMethod", returnType: typeof(int), parameterTypes: new[] { typeof(int) }, m: typeof(Program).Module); //تعریف بدنه متد var il = myMethod.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); // اولین آرگومان متد را بر روی پشته قرار میدهد il.Emit(OpCodes.Ldc_I4, 42); // عدد ثابت 42 را بر روی پشته قرار میدهد il.Emit(OpCodes.Mul); // ضرب این دو در هم il.Emit(OpCodes.Ret); // بازگشت نتیجه //فراخوانی متد پویا var method = (Func<int, int>)myMethod.CreateDelegate(typeof(Func<int, int>)); Console.WriteLine(method(10)); // فراخوانی متد پویای فوق در یک متد پویای دیگر var callerMethod = new DynamicMethod( name: "callerMethod", returnType: typeof(int), parameterTypes: new[] { typeof(int), typeof(int) }, m: typeof(Program).Module); //تعریف بدنه متد var callerMethodIL = callerMethod.GetILGenerator(); callerMethodIL.Emit(OpCodes.Ldarg_0); // پارامتر اول متد را بر روی پشته قرار میدهد callerMethodIL.Emit(OpCodes.Ldarg_1); // پارامتر دوم متد را بر روی پشته قرار میدهد callerMethodIL.Emit(OpCodes.Mul); // ضرب این دو در هم //حاصل ضرب اکنون بر روی پشته است که در فراخوانی بعدی استفاده میشود callerMethodIL.Emit(OpCodes.Call, myMethod); // فراخوانی یک متد پویای دیگر callerMethodIL.Emit(OpCodes.Ret); //فراخوانی متد پویای جدید var method2 = (Func<int, int, int>)callerMethod.CreateDelegate(typeof(Func<int, int, int>)); Console.WriteLine(method2(10, 2)); } } }
dotnet ef dbcontext scaffold "Data Source=(local);Initial Catalog=BloggingCore2016;Integrated Security = true" Microsoft.EntityFrameworkCore.SqlServer -o Entities --context MyDBDataContext --verbose
using System; using System.Collections.Generic; namespace Core1RtmEmptyTest.Entities { public partial class Blog { public Blog() { Post = new HashSet<Post>(); } public int BlogId { get; set; } public string Url { get; set; } public virtual ICollection<Post> Post { get; set; } } }
using System; using System.Collections.Generic; namespace Core1RtmEmptyTest.Entities { public partial class Post { public int PostId { get; set; } public string Content { get; set; } public string Title { get; set; } public virtual Blog Blog { get; set; } public int BlogId { get; set; } } }
using System; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata; namespace Core1RtmEmptyTest.Entities { public partial class MyDBDataContext : DbContext { protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseSqlServer(@"Data Source=(local);Initial Catalog=BloggingCore2016;Integrated Security = true"); } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Blog>(entity => { entity.Property(e => e.Url).IsRequired(); }); modelBuilder.Entity<Post>(entity => { entity.HasOne(d => d.Blog) .WithMany(p => p.Post) .HasForeignKey(d => d.BlogId); }); } public virtual DbSet<Blog> Blog { get; set; } public virtual DbSet<Post> Post { get; set; } } }
public virtual Blog Blog { get; set; }
public virtual ICollection<Post> Post { get; set; }
<primary key property name> <navigation property name><primary key property name> <principal entity name><primary key property name>
public virtual Blog Blog { get; set; } public int BlogId { get; set; }
modelBuilder.Entity<Post>(entity => { entity.HasOne(d => d.Blog) .WithMany(p => p.Post) .HasForeignKey(d => d.BlogId); });
dotnet ef dbcontext scaffold "Data Source=(local);Initial Catalog=BloggingCore2016;Integrated Security = true" Microsoft.EntityFrameworkCore.SqlServer -o Entities --context MyDBDataContext --verbose -a
using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace Core1RtmEmptyTest.Entities { public partial class Blog { public Blog() { Post = new HashSet<Post>(); } public int BlogId { get; set; } [Required] public string Url { get; set; } [InverseProperty("Blog")] public virtual ICollection<Post> Post { get; set; } } }
using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace Core1RtmEmptyTest.Entities { public partial class Post { public int PostId { get; set; } public string Content { get; set; } public string Title { get; set; } [ForeignKey("BlogId")] [InverseProperty("Post")] public virtual Blog Blog { get; set; } public int BlogId { get; set; } } }
using System; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata; namespace Core1RtmEmptyTest.Entities { public partial class MyDBDataContext : DbContext { protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseSqlServer(@"Data Source=(local);Initial Catalog=BloggingCore2016;Integrated Security = true"); } protected override void OnModelCreating(ModelBuilder modelBuilder) { } public virtual DbSet<Blog> Blog { get; set; } public virtual DbSet<Post> Post { get; set; } } }
[ForeignKey("BlogId")] [InverseProperty("Post")] public virtual Blog Blog { get; set; } public int BlogId { get; set; }
[InverseProperty("Blog")] public virtual ICollection<Post> Post { get; set; }
public virtual Blog Blog { get; set; }
var firstPost = context.Post.First(); Console.WriteLine(firstPost.Blog.Url);
System.NullReferenceException Object reference not set to an instance of an object.
var firstPost = context.Post.Include(x => x.Blog).First(); Console.WriteLine(firstPost.Blog.Url);
var blogs = context.Blogs .Include(blog => blog.Posts) .Include(blog => blog.Owner) .ToList();
var blogs = context.Blogs .Include(blog => blog.Posts) .ThenInclude(post => post.Author) .ToList();
var blogs = context.Blogs .Include(blog => blog.Posts) .ThenInclude(post => post.Author) .ThenInclude(author => author.Photo) .ToList();
var blogs = context.Blogs .Include(blog => blog.Posts) .ThenInclude(post => post.Author) .ThenInclude(author => author.Photo) .Include(blog => blog.Owner) .ThenInclude(owner => owner.Photo) .ToList();
var blogs = context.Blogs .Include(blog => blog.Posts) .Select(blog => new { Id = blog.BlogId, Url = blog.Url }) .ToList();
CONSTRAINT [FK_Post_Blog_BlogId] FOREIGN KEY ([BlogId]) REFERENCES [Blog] ([BlogId]) ON DELETE CASCADE
modelBuilder.Entity<Post>() .HasOne(p => p.Blog) .WithMany(b => b.Posts) .OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<Post>() .HasOne(p => p.Blog) .WithMany(b => b.Posts) .IsRequired();