معرفی کد آنالیزر Serilog
همانطور که میدانید Serilog قویترین و محبوبترین کتابخانه Logging در دات نت است. اگر از آن استفاده میکنید پیشنهاد میکنم افزونه و کتابخونه زیر رو هم نصب کنین
ابزار Serilog Analyzer یک آنالیزر roslyn-based برای Serilog بوده و خطاهای رایج و اشتباهات متداول به هنگام استفاده از Serilog را گوشزد کرده و اصلاح میکند.
دیالوگ های بوت استراپ با استفاده از jquery
روش به کارگیری تقویم در Blazor
<link href="css/js-persian-cal.css" rel="stylesheet"/>
<script src="js/js-persian-cal.min.js"></script>
<input type="text" id="pcal1" />
protected override async Task OnAfterRenderAsync(bool firstRender) { int dateFieldCount = 1; if (firstRender) { for (int i = 1; i <= dateFieldCount; i++) { await JsRuntime.InvokeVoidAsync("CallAmib", "pcal" + i.ToString()); } } }
@inject IJSRuntime JsRuntime
window.CallAmib = (objCal1) => { new AMIB.persianCalendar(objCal1); }
@using Microsoft.AspNetCore.Components.Web @namespace ShamsiDatePickerBlazor.Pages @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <base href="~/" /> <link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" /> <link href="css/site.css" rel="stylesheet" /> <link href="css/js-persian-cal.css" rel="stylesheet" /> <component type="typeof(HeadOutlet)" render-mode="ServerPrerendered" /> </head> <body> @RenderBody() <div id="blazor-error-ui"> <environment include="Staging,Production"> An error has occurred. This application may no longer respond until reloaded. </environment> <environment include="Development"> An unhandled exception has occurred. See browser dev tools for details. </environment> <a href="">Reload</a> <a>🗙</a> </div> <script src="js/js-persian-cal.min.js"></script> <script src="js/CallAmib.js"></script> <script src="_framework/blazor.server.js"></script> </body> </html>
مشکل!!
window.CallCall = (objCal1) => { new AMIB.persianCalendar(objCal1,{ onchange: function(pdate) { DotNet.invokeMethodAsync('ShamsiDatePickerBlazor', 'DateChanged', pdate.toString()).then( (date) => { console.log(data); } ); } }); }
static string selectedDate; [JSInvokable] public static void DateChanged(string pdate) { selectedDate = pdate; }
محل ذخیره شدن بانک اطلاعاتی time-zones در اندروید
بسته به نگارش اندروید شما، یکی از مکانهای زیر، محل ذخیره سازی دو فایل tzdata و tz_version است:
/data/misc/zoneinfo/tzdata /system/usr/share/zoneinfo /apex/com.android.tzdata/etc/tz/tzdata
مشکل! به روز رسانی مسیرهای سیستمی اندروید، نیاز به دسترسی root دارند!
تا اینجا مشخص شد که برای رفع مشکل time-zone و به روز رسانی اطلاعات آن، باید دو فایل tzdata و tz_version را در مسیرهای یاد شده، بازنویسی کنیم؛ اما ... اندروید چنین اجازهای را نمیدهد!
در سیستم عامل LineageOS 17.1 ای که من نصب کردم، میتوان با نصب برنامهی معروف Magisk، دسترسی روت پیدا کرد. روش نصب آن هم به صورت زیر است:
1) فایل apk آنرا از این آدرس دریافت کرده و پسوند آنرا به zip. تغییر دهید.
2) سیستم را ریاستارت کرده و رفتن به گزینهی recovery را انتخاب کنید تا پس از ریاستارت سیستم، وارد برنامهی TWRP شویم (که روش نصب آن در مطلب جاری بحث شده).
3) در برنامهی TWRP، گزینهی install را انتخاب و سپس فایل zip. برنامهی magisk را انتخاب و نصب کنید.
4) پس از نصب، یکبار هم کش را پاک کنید (Wipe cache/dalvik).
5) در آخر بر روی دکمهی Reboot System تا ... وارد اندروید شوید.
6) پس از راه اندازی سیستم، برنامهی Magisk را اجرا کنید تا مرحلهی آخر نصب آن به پایان برسد (یکسری از فایلها را نیاز دارد تا از اینترنت دریافت و نصب کند؛ این نصب، از github و به صورت خودکار است).
پس از نصب magisk، برنامهی total commander را هم نصب کنید. به محض اجرای آن، پیام درخواست دسترسی root آن هم ظاهر میشود (این برنامهی magisk هست که این درخواست را تشخیص داده و مدیریت میکند) و نیاز است این دسترسی را بدهید تا بتوان:
1) به مسیر file system root و سپس apex/com.android.tzdata/etc/tz/tzdata وارد شد و دو فایل موجود و قدیمی tzdata و tz_version را به نحو متداولی پاک کرد.
2) سپس دو فایل جدید tzdata و tz_version را (که لینک دریافت آن کمی بالاتر ارائه شد) به سیستم خود منتقل کنید (همانند تمام فایلهای دیگر از طریق usb) و در آخر با استفاده از total commander ای که اکنون دسترسی root هم دارد، این فایلها را به مسیر یاد شده، کپی کنید.
MongoDB #3
محیط MongoDB
نصب MongoDB در ویندوز
برای نصب MongoDB در ویندوز، اول باید آخرین نسخه MongoDB را از آدرس http://www.mongodb.org/downloads دریافت کنید. مطمئن شوید که نسخهی صحیحی از MongoDB را نسبت به معماری ویندوزتان دریافت کردهاید. برای پیدا کردن معماری ویندوز، پنجرهی Command Prompt را باز کنید و دستور زیر را اجرا کنید:
C:\>wmic os get osarchitecture OSArchitecture 64-bit C:\>
نسخههای 32بیتی MongoDB فقط پایگاه دادههای کوچکتر از 2 گیگابایت را پشتیبانی میکنند و صرفا برای تست و ارزیابی مناسب هستند. اکنون فایل دریافتی را نصب کنید. MongoDB یک پوشه داده، برای ذخیره فایلهایش نیاز دارد. مسیر پیش فرض پوشه داده c:\data\db است؛ بنابراین نیاز دارید این پوشه را بسازید. شما میتوانید یک مسیر دیگر را نیز برای مسیر داده تنظیم کنید. برای انجام این کار، Command Prompt را در پوشه bin (در مسیر نصب شده MongoDB) باز کنید و دستور زیر را اجرا کنید: (فرض کنید MongoDB در مسیر D:\set up\mongodb نصب شده است)
D:\set up\mongodb\bin>mongod.exe --dbpath "d:\set up\mongodb\data"
بعد از اجرای دستور، پیام “waiting for connections” در کنسول نمایش داده میشود که نشان دهندهی این است که پروسه Mongod.exe با موفقیت اجرا شده است. حالا برای اجرای MongoDB یک Command Prompt دیگر نیاز دارید تا دستور زیر را اجرا کنید:
D:\set up\mongodb\bin>mongo.exe MongoDB shell version: 2.6.6 connecting to: test >db.test.save( { a: 1 } ) >db.test.find() { "_id" : ObjectId(5879b0f65a56a454), "a" : 1 } >
این دستور نشان خواهد داد که MongoDB نصب و با موفقیت اجرا شدهاست. برای اجرای MongoDB در دفعات بعدی نیز همین 2 مرحله را تکرار کنید (تعیین مسیر پوشه داده و اجرای Mongo.exe در یک Command Prompt دیگر).
نصب MongoDB در اوبونتو
دستور زیر را برای وارد کردن کلید GPG عمومی MongoDB در ترمینال اجرا کنید:
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10
فایل /etc/apt/sources.list.d/mongodb.list را با دستور زیر بسازید:
echo 'deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen' | sudo tee /etc/apt/sources.list.d/mongodb.list
اکنون دستور زیر را برای بروز رسانی مخازن پکیجها اجرا کنید:
sudo apt-get update
حالا MongoDB را با استفاده از دستور زیر نصب کنید:
apt-get install mongodb-10gen=2.2.3
در دستور نصب فوق، به نسخهی 2.2.3 از MongoDB انتشار شده است. همیشه مطمئن شوید که آخرین نسخه را نصب کرده اید. اکنون MongoDB با موفقیت نصب شده است.
راه اندازی MongoDB
sudo service mongodb start
متوقف کردن MongoDB
sudo service mongodb stop
راه اندازی مجدد MongoDB
sudo service mongodb restart
برای استفاده از MongoDB از دستور زیر استفاده کنید:
Mongo
این دستور شما را به نمونهی در حال اجرای Mongod متصل خواهد کرد.
راهنمای MongoDB
برای دریافت لیست دستورات، ()db.help را در نسخه کلاینت MongoDB تایپ کنید. این دستور، لیست دستورات را مانند تصویر زیر به شما میدهد:
آمار و ارقام در MongoDB
برای گرفتن آمار و ارقام از MongoDB سرور، دستور ()db.stats را در نسخه کلاینت MongoDB تایپ کنید. این دستور نام پایگاه داده، تعداد مجموعهها و سندهای موجود در پایگاه داده را نمایش میدهد:
- در مورد سوئیچ startup-project در مطلب « شروع به کار با EF Core 1.0 - قسمت 3 - انتقال مهاجرتها به یک اسمبلی دیگر» بحث شدهاست.
- این پروژه از فایل _01-add_migrations.cmd برای افزودن مهاجرتها استفاده میکند و از فایل _02-update_db.cmd برای به روز رسانی ساختار بانک اطلاعاتی.
- ادغام چند فایل PDF به صورت فایل واحد (Merging)
- اضافه کردن یک فایل PDF به یک فایل موجود (Appending)
- جدا کردن صفحات دلخواه از یک فایل و ذخیره آنها در یک فایل جدا (Splitting)
- در صورت نصب امکانات پایتون برای ویژوال استودیو مثل سایر پروژههای دات نت قابل اجرا و دیباگ است.
- از طریق خط فرمان و دستور ipy که در ادامه مثالی میزنم.
- من خودم از طریق یک برنامه کنسول ساده پروژه را خارج از محیط توسعه اجرا میکنم که در ادامه مثالی میزنم.
var process = new Process(); var startInfo = new ProcessStartInfo { WindowStyle = ProcessWindowStyle.Hidden, FileName = "CMD.exe", Arguments = "/C ipy C:\\PdfTools\\PdfTools.py" }; process.StartInfo = startInfo; process.Start();
الف) تزریق وابستگیها در سازنده کلاس
ب) تزریق وابستگیها در خواص عمومی کلاسها یا Setters injection
حالت الف متداولترین است و بیشتر زمانی کاربرد دارد که کار وهله سازی یک کلاس را میتوان راسا انجام داد. اما در فرمها یا یوزرکنترلهای ASP.NET Web forms به صورت پیش فرض کار وهله سازی فرمها و یوزرکنترلها توسط موتور ASP.NET انجام میشود و در این حالت اگر بخواهیم از تزریق وابستگیها استفاده کنیم، مدام به همان روش معروف Service locator و استفاده از container.Resolve در تمام قسمتهای برنامه میرسیم که آنچنان روش مطلوبی نیست.
اما ... در ASP.NET Web forms میتوان وهله سازی فرمها را نیز تحت کنترل قرار داد، که برای آن دو روش زیر وجود دارند:
الف) یک کلاس مشتق شده را از کلاس پایه PageHandlerFactory تهیه کنیم. این کلاس را پیاده سازی کرده و نهایتا بجای وهله ساز پیش فرض فرمهای موتور داخلی ASP.NET، در فایل وب کانفیگ برنامه استفاده کنیم. یک نمونه از پیاده سازی آنرا در اینجا میتوانید مشاهده کنید.
مشکلی که این روش دارد سازگاری آن با حالت Full trust است. یعنی برنامه شما در یک هاست Medium trust (اغلب هاستهای خوب) اجرا نخواهد شد.
ب) روش دوم، استفاده از یک Http Module است برای اعمال Setter injectionها، به صورت خودکار. اکنون که حالت الف را همه جا نمیتوان بکار برد یا به عبارتی نمیتوان وهله سازی فرمها را راسا در دست گرفت، حداقل میتوان خواص عمومی اشیاء صفحه تولید شده را مقدار دهی کرد که در ادامه، این روش را بررسی میکنیم.
تهیه ماژول انجام Setters injection به صورت خودکار در برنامههای ASP.NET Web forms به کمک StructureMap
پیشنیاز این بحث، مطلب «استفاده از StructureMap به عنوان یک IoC Container» میباشد که پیشتر مطالعه کردید (در حد نحوه نصب StructureMap و آشنایی با تنظیمات اولیه آن)
using System.Collections; using System.Web; using System.Web.UI; using StructureMap; namespace DI05.Core { /// <summary> /// تسهیل در کار تزریق خودکار وابستگیها در سطح فرمها و یوزرکنترلها /// </summary> public class StructureMapModule : IHttpModule { public void Dispose() { } public void Init(HttpApplication app) { app.PreRequestHandlerExecute += (sender, e) => { var page = HttpContext.Current.Handler as Page; // The Page handler if (page == null) return; WireUpThePage(page); WireUpAllUserControls(page); }; } private static void WireUpAllUserControls(Page page) { // در اینجا هم کار سیم کشی یوزر کنترلها انجام میشود page.InitComplete += (initSender, evt) => { var thisPage = (Page)initSender; foreach (Control ctrl in getControlTree(thisPage)) { // فقط یوزر کنترلها بررسی شدند // اگر نیاز است سایر کنترلهای قرار گرفته روی فرم هم بررسی شوند شرط را حذف کنید if (ctrl is UserControl) { ObjectFactory.BuildUp(ctrl); } } }; } private static void WireUpThePage(Page page) { ObjectFactory.BuildUp(page); // برقراری خودکار سیم کشیها در سطح صفحات } private static IEnumerable getControlTree(Control root) { foreach (Control child in root.Controls) { yield return child; foreach (Control ctrl in getControlTree(child)) { yield return ctrl; } } } } }
پس از تهیه ماژول فوق، باید آنرا در فایل وب کانفیگ برنامه معرفی کرد:
<?xml version="1.0"?> <configuration> <system.web> <compilation debug="true" targetFramework="4.0" /> <httpModules> <add name="StructureMapModule" type="DI05.Core.StructureMapModule"/> </httpModules> </system.web> <system.webServer> <modules runAllManagedModulesForAllRequests="true"> <add name="StructureMapModule" type="DI05.Core.StructureMapModule"/> </modules> <validation validateIntegratedModeConfiguration="false" /> </system.webServer> </configuration>
مثالی از نحوه استفاده از StructureMapModule تهیه شده
فرض کنید لایه سرویس برنامه دارای اینترفیسها و کلاسهای زیر است:
namespace DI05.Services { public interface IUsersService { string GetUserEmail(int id); } } namespace DI05.Services { public class UsersService: IUsersService { public string GetUserEmail(int id) { //فقط جهت بررسی تزریق وابستگیها return "test@test.com"; } } }
using System; using StructureMap; using DI05.Services; namespace DI05 { public class Global : System.Web.HttpApplication { private static void initStructureMap() { ObjectFactory.Initialize(x => { x.For<IUsersService>().Use<UsersService>(); x.SetAllProperties(y => { y.OfType<IUsersService>(); }); }); } protected void Application_Start(object sender, EventArgs e) { initStructureMap(); } void Application_EndRequest(object sender, EventArgs e) { ObjectFactory.ReleaseAndDisposeAllHttpScopedObjects(); } } }
مرحله آخر هم استفاده از سرویسهای برنامه به شکل زیر است:
using System; using DI05.Services; namespace DI05 { public partial class Default : System.Web.UI.Page { public IUsersService UsersService { set; get; } protected void Page_Load(object sender, EventArgs e) { lblEmail1.Text = string.Format("From Default Page: {0}", UsersService.GetUserEmail(1)); } } }
دریافت مثال کامل قسمت جاری
DI05.zip
یک نکتهی تکمیلی
برای ارتقاء نکات مطلب جاری به نگارش سوم StructureMap نیاز است موارد ذیل را لحاظ کنید:
الف) نصب بستهی وب آن
PM> Install-Package structuremap.web
ج) x.SetAllProperties را به x.Policies.SetAllProperties ویرایش کنید.
نگارش نهایی NET Core 2.1. منتشر شد
{ "sdk": { "version": "number ....." } }