آشنایی با فریمورک الکترون Electron
توابع تعمیم یافته در #C
البته توسعه تعداد توابع نیز به نوعی توسعه توابع است و الزامی ندارد فقط یک تابع توسعه یابد تا تعمیم و توسعه صدق کند
البته الحاق هم صحیح است .
نکته دیگر آنکه برای متد و فانکشن و مانند آن در فارسی معادلی غیر تابع ندیدهام که متداول باشد. بعلاوه آنکه تابع مفهوم همه اینها را شامل میشود خواه نوع بازگشتی داشته باشد یا void باشد، لذا تعبیر غیر صحیحی نیست
باتشکر
EF Code First #10
شما زمانی میتونید از lazy loading برای بارگذاری اشیاء مرتبط مانند حلقه زیر استفاده کنید:
foreach (var dept in db.Departments) { Console.WriteLine(dept.Name); foreach (var item in dept.Employees) { Console.WriteLine(item.FirstName); } }
در WCF یکبار اطلاعات serialize شده و اتصال بسته میشود (البته WCF فراتر است از حالت http binding ساده؛ ولی عموما این مورد در برنامههای وب مدنظر است). بنابراین اینبار اگر dept.Employees را روی لیست تهیه شده فراخوانی کنید، پیغام بسته بودن اتصال رو دریافت میکنید. به همین جهت اگر نیاز به اطلاعات کارمندان هم هست، همه را باید به یکباره از سرور دریافت کرد.
چندی پیش موسسان تلگرام با معرفی APIهای کاربردی، به توسعه کنندگان اجازه دادند که با بهره گیری از بستر این شبکه، اقدام به تولید اینترفیسی به اسم بات کنند که با دریافت دستورات سفارشی، عملیات خاصی را انجام دهد.
در واقع تلگرام و متدهای ارائه شده، یک راه ارتباطی بین کاربران و برنامههای تولید شده را ایجاد کردند که با قدری ذوق و سلیقه، شاهد باتهای جالب و کاربردی هستیم.
در این مقاله سعی شده طرز تهیه یک بات با زبان #C توضیح داده شود.
در ابتدا شما باید توسط یکی از باتهای اصلی تلگرام اقدام به ثبت نام کاربری و تنظیمات بات مورد نظر خودتان نمایید. بات مورد نظر @BotFather میباشد که با شروع مکالمه میتوان با فرستادن دستورات مختلف تنظیمات مختلفی را انجام داد. با شروع مکالمه با بات مورد نظر با دستور /start دستورات زیر قابل انجام میباشد:
You can control me by sending these commands : / newbot - create a new bot / token - generate authorization token / revoke - revoke bot access token / setname - change a bot's name / setdescription - change bot description / setabouttext - change bot about info / setuserpic - change bot profile photo / setcommands - change bot commands list / setjoingroups - can your bot be added to groups ? / setprivacy - what messages does your bot see in groups ? / deletebot - delete a bot / cancel - cancel the current operation
بعد از تایید نام و یوزر نیم، به شما یک توکن اختصاص داده میشود که توسط آن شما شناسایی میشوید.
در اینجا شما میتوانید تنظیمات اضافهتری مانند عکس برای پروفایل و غیره را نیز تنظیم کنید.
در مرحلهی بعد میتوانید در همین قسمت دستورات مورد نظر را جهت بات خود تنظیم کنید. برای این کار باید دستور /setcommands را وارد کنید و دستور مورد نظر خود را به فرمت command1 – Description وارد کنید.
مرحلهی بعد، تنظیمات برنامهی شما جهت دریافت دستورات وارد شده و انجام عملیات مورد نظر و تولید و ارسال خروجی مورد نظر است.
دریافت دستورات به دو طریق انجام میشود:
1. توسط دستور getUpdates میتوان تمامی کامندهای دریافتی را از سرور تلگرام دریافت کرد و با انجام پروسسهای لازم، خروجی را به کاربر مورد نظر ارسال کرد.
2. توسط تابع webhook از تلگرام درخواست کرد در صورت دریافت دستور جدید به بات، این دستور را به یک آدرس خاص ارسال کرد.
قابل توجه است که میتوان فقط از یکی از دو روش فوق استفاده کرد. همچنین در روش دوم حتما سرور مورد نظر باید گواهی ssl تایید شده داشته باشد.
کد زیر دریافت کامندهای یک بات به روش اول میباشد :
public class mydata { public result[] result; } public class result { public int update_id { get; set; } public message message { get; set; } } public class message { public int message_id { get; set; } public message_from from { get; set; } public message_chat chat { get; set; } public int date { get; set; } public string text { get; set; } } public class message_from { public int ind { get; set; } public string first_name { get; set; } public string username { get; set; } } public class message_chat { public int id { get; set; } public string first_name { get; set; } public string username { get; set; } } public Void GetUpdates() { WebRequest req = WebRequest.Create("https://api.telegram.org/bot" + yourToken + "/getUpdates"); req.UseDefaultCredentials = true; WebResponse resp = req.GetResponse(); Stream stream = resp.GetResponseStream(); StreamReader sr = new StreamReader(stream); string s = sr.ReadToEnd(); sr.Close(); var jobject = Newtonsoft.Json.Linq.JObject.Parse(s); mydata gg = JsonConvert.DeserializeObject<mydata>(jobject.ToString()); List<result> results = new List<result>(); foreach (result rs in gg.result) { results.Add(rs); SendMessage(rs.message.chat.id.ToString(), "hello"+" "+"Dear"+rs.message.chat.first_name); } }
public static void SendMessage(string chat_id, string message) { WebRequest req = WebRequest.Create("https://api.telegram.org/bot" + youToken + "/sendMessage?chat_id=" + chat_id + "&text=" + message); req.UseDefaultCredentials = true; var result = req.GetResponse(); req.Abort(); }
لازم به ذکر است خروجی توابع باتهای تلگرام با فرمت JSON میباشد که با نصب پکیج NewTonsoft میتوان آن را به لیست تبدیل کرد.
rs.message.chat.id، آی دی فردی است که به بات تلگرامی ما مسیج ارسال کرده است.
rs.message.chat.first_name نام فردی است که به بات تلگرام مسیج ارسال کرده است.
همچنین میتوان در جواب کامند بات، علاوه بر متن، صدا و تصویر را نیز ارسال نمود .
در این لینک و این لینک میتوان توضیحات بیشتری را در این زمینه مطالعه کرد.
در انتها خوشحال میشوم ذوقها و ایدههای شما را در ساخت باتها با آیدی @iekhtiari مشاهده کنم.
- استفاده از WebHost.CreateDefaultBuilder: این روش جهت تنظیم شروع به کار یک برنامهی ASP.NET Core 2x مورد استفاده قرار میگرفت.
- استفاده از Host.CreateDefaultBuilder: روش پیشفرض آغاز برنامههای وب NET Core 3x. و NET 5x. که با معرفی generic host، امکان تهیهی Worker services را میسر کردند.
- استفاده از WebApplication.CreateBuilder: روش جدید شروع به کار با برنامههای وب مبتنی بر NET 6.
استفاده از WebHost.CreateDefaultBuilder در ASP.NET Core 2.x
در نگارش اول ASP.NET Core، مفهومی به نام هاست پیشفرض (default host) وجود نداشت. یکی از مهمترین نکات درنظر گرفته شده در طراحی ASP.NET Core، مفهوم «هزینه کردن به ازای احتیاج» است. یعنی اگر نیاز به قابلیتی نیست، نباید وجود داشته باشد. به این ترتیب یک قالب آغازین نباید به همراه تعداد زیادی بستههای NuGet و مقدار زیادی کد برای تنظیم باشد؛ زمانیکه واقعا قرار نیست از تمام آنها استفاده شود. به همین جهت از نگارش 2، شروع به سادهکردن این قالب اولیه کردند و در این زمان، WebHost.CreateDefaultBuilder ارائه شد. این تنظیم به ظاهر ساده، کدهای پیشفرض مورد نیاز قابل توجهی را جهت ساخت سادهی IWebHostBuilder و IWebHost به همراه دارد. در قالب به همراه آن، بین مفاهیم تنظیمات application و host تفاوت قائل شدهاند؛ یعنی دو فایل Program.cs را برای تنظیمات application و فایل Startup.cs را برای ارائهی تنظیمات هاست، تدارک دیدند.
در این طراحی، بین میدان دید Program و Startup تفاوت وجود دارد. هدف از Program، ارائهی تنظیمات زیرساختی برنامه، مانند تنظیمات HTTP Server، یکپارچگی با IIS و امثال آن شد و عموما در طول عمر برنامه ثابت است. اما برای تغییر رفتار برنامه، بیشتر تغییرات و تنظیمات، به Startup محول شدند؛ مانند تنظیمات تزریق وابستگیها، تنظیمات میانافزارها، مسیریابیها و غیره.
public class Program { public static void Main(string[] args) { BuildWebHost(args).Run(); } public static IWebHost BuildWebHost(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>() .Build(); }
معرفی Generic Host در ASP.NET Core 3.x/5
ASP.NET Core 3.x به همراه تغییرات بزرگی در کدهای آغازین برنامههای ASP.NET Core بود. تا پیش از آن، امکانات پایهی ASP.NET Core تنها برای مقاصد وب قابل استفاده بود. اما در نگارشهای 3x، با ارائهی یک هاست عمومی، امکان پشتیبانی از سایر برنامهها، مانند worker services را نیز میسر کرد؛ برای مثال پیشتیبانی از کارهای طولانی پس زمینه، هاست سرویسهای gRPC، هاست سرویسهای ویندوز و غیره. هدف اصلی از این تغییرات، به اشتراک گذاری فریمورک پایهی ASP.NET Core که تنها برای برنامههای وب ساخته شده بود و به همراه امکاناتی مانند تنظیمات، ثبت وقایع، تزریق وابستگیها و غیره بود، با سایر انواع برنامههای یاد شده است. برای رسیدن به این هدف، Web Host نگارش 2x، به Generic Host نگارش 3x تغییر کرد و سپس ASP.NET Core برفراز آن بنا شد. اینبار بجای IWebHostBuilder، نمونهی جدید IHostBuilder را داریم:
public class Program { public static void Main(string[] args) { CreateHostBuilder(args).Build().Run(); } public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); }; } }
ASP.NET Core 5 به همراه تغییرات مهمی در این زمینه نبود و تنها با تغییر target framework در فایل csproj و به روز رسانی بستههای نیوگت مرتبط، کار ارتقاء به نگارش جدید در آن صورت میگرفت.
معرفی WebApplicationBuilder در ASP.NET Core 6x
در دات نت 6، روش آغاز برنامههای وب بطور کامل تغییر کردهاست. در تمام نگارشهای پیشین ASP.NET Core، همواره شاهد دو فایل Program.cs و Startup.cs بودیم؛ اما در اینجا فقط یک فایل Program.cs بیشتر وجود ندارد. هر چند همانطور که در مطلب «ارتقاء فایلهای آغازین برنامههای ASP.NET Core 5x به 6x» نیز عنوان شد، میتوان همان سبک و سیاق پیشین را نیز برگرداند و از این لحاظ محدودیتی وجود ندارد.
var builder = WebApplication.CreateBuilder(args); builder.Services.AddRazorPages(); var app = builder.Build(); if (app.Environment.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseStaticFiles(); app.MapGet("/", () => "Hello World!"); app.MapRazorPages(); app.Run();
- استفاده از top level statements
- استفاده از usingهای سراسری و سایر قابلیتهای C# 10.0
- حذف کامل کلاس Startup؛ اینبار همه چیز فقط یک فایل است.
دیدگاهی را که در اینجا بکار گرفتهاند شامل این موارد است و بیشتر تازهواردان را مدنظر دارند:
- برای شروع به کار، using statements اضافی هستند؛ پس حذف شدهاند!
- برای شروع به کار، namespaces اضافی هستند؛ پس حذف شدهاند!
- برای شروع به کار، Program.Main ... هم اضافی است!
- تنظیمات بین دو فایل Program.cs و Startup.cs تقیسم نشدهاند و همهچیز یکجا است و این هم نیازی به توضیح اضافی به تازهواردان، ندارد.
- همچنین همانطور که عنوان شد، « ... متد UseStartup به صورت خودکار به دنبال متدهای ویژهی ConfigureServices و Configure در کلاس آغازین برنامه گشته و آنها را فراخوانی میکند تا تنظیمات تزریق وابستگیها، مسیریابیها و میانافزارها صورت گیرند ...»
نکتهی مهم این توضیح، این است که کلاس Startup، هیچ اینترفیسی را پیاده سازی نمیکند. یعنی نام این متدها، دقیقا باید به همین صورت باشند (بدون اینکه قرار دادی توسط یک اینترفیس برای آنها وضع شده باشد) و ... چرا واقعا باید به این صورت باشد؟! به همین جهت اینها هم حذف شدهاند!
- در اینجا WebApplication هم مشاهده میشود؛ اما آیا واقعا نیازی به آن است؟
پاسخ: خیر! WebApplication.CreateBuilder ای که در اینجا ملاحظه میکنید در حقیقت ساده شدهی قطعه کد زیر از کدهای ASP.NET Core 3x/5x است:
var hostBuilder = Host.CreateDefaultBuilder(args) .ConfigureServices(services => { services.AddRazorPages(); }) .ConfigureWebHostDefaults(webBuilder => { webBuilder.Configure((ctx, app) => { if (ctx.HostingEnvironment.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseStaticFiles(); app.UseRouting(); app.UseEndpoints(endpoints => { endpoints.MapGet("/", () => "Hello World!"); endpoints.MapRazorPages(); }); }); }); hostBuilder.Build().Run();
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages(); builder.Services.AddSingleton<MyThingy>();
builder.Logging.AddFile();
var app = builder.Build();
app.UseStaticFiles(); app.MapRazorPages();
در پنجره ای که باز میشود ، لیست را نام گذاری میکنیم
سپس یک View ایحاد میکنیم . برای این کار از نوار Ribbon بالا ، روی List View کلیک میکینم :
سپس نامی برای این View در نظر میگیریم و این Viewرا به عنوان نمای پیش فرض انتخاب میکنیم
در این مرحله نمای نگاهی به لیست در مرور گر میاندازیم و تعدادی داده برای آزمایش در آن وارد میکنیم
حال برای اعمال تغییرات به SPD برمیگردیم و روی View ساخته شده کلیک میکنیم تا وارد محیط ویرایش آن شویم .
در این مثال میخواهم روی فیلد نام شرکت فیلتر انجام دهم
سپس برای تغییر نحوه نمایش ، روی Set Style کلیک میکنیم :
پس از اعمال تغییرات میتوانید تغییرات را در کد مشاهده کنید
برای اعمال تغییرات در خروجی و ستونهای آن ، روی Add/Remove Columns کلیک میکنیم :
برای مثال در اینجا ستون Job Title را به لیست اضافه کردم :
همچنین برای اعمال Inline Editing به عناصر لیست میتوانید روی دکمه ای با همین نام در Ribbon کلیک کنید
در ادامه میتوانید عملیات مرتب سازی و گروه بندی اطلاعات را هم تنها با چند کلیک مدیریت کنید
در اینجا گروه بندی و مرتب سازی را روی نام شرکت اعمال میکنیم :
تا کنون خروجی پیش نمایش داده شده در SPD به این صورت است :
تغییرات را ذخیره میکنیم :
و خروجی را در مرور گر مشاهده میکنید (همانطور که مشاهده میکنید ، ویرایش خطی برای آیتمها فعال شده است و همین طور گروه بندی بر اساس نام شرکت و مرتب سازی نیز اعمال شده است . همچنین رنگ سطر هایی که نام شرکت آنها Alfa است ، تغییر کرده است ) :
اکنون میخواهم قسمتی از تغییرات اعمال شده را از طریق مرور گر ( و نه SPD) تغییر دهم . برای این کار روی List در Ribbon کلیک میکنیم :
در قسمت Group by تنظیمات ستون را روی none قرار میدهیم تا گروه بندی اعمال نشود :