تبدیل html به pdf با کیفیت بالا
using (var converter = new Converter()) { converter.ConvertToPdf(new ConvertUri(SourcePath), "output.pdf", new PageSettings(PaperFormat.A4) { DisplayHeaderFooter = true, HeaderTemplate = header, FooterTemplate = footer, PrintBackground = true, }); converter.ConvertToImage(new ConvertUri(tempSourcePath), "output.png", new PageSettings(PaperFormat.A6)); }
var header = """ <div class="text center" style="color: lightgray;border-bottom: solid lightgray 0.1px; width: 100%; font-family: 'Samim'; font-size:7px;"> <span class="title"></span> </div> """; var footer = """ <div class="text center" style="color: lightgray; font-family: 'Samim'; font-size:7px;"> <span class="pageNumber"></span>/<span class="totalPages"></span> </div> """;
var HTML = "<HTML code>"; using (Converter converter = new Converter()) using (MemoryStream stream = new MemoryStream()) { // This is necessary when running on Docker converter.AddChromeArgument("--no-sandbox"); // Create PDF out of HTML string converter.ConvertToPdf(html, stream, new ChromeHtmlToPdfLib.Settings.PageSettings()); // Return file to user return File(stream.ToArray(), MediaTypeNames.Application.Pdf, "Report.pdf"); }
- Convert.Net
- Regular Expression Tester : که جهت تست Regexهای نوشته شده استفاده میشود.
- Encoding & Decoding : جهت تبدیل انواع رشتههای Encoded ویا Decoded به یکدیگر استفاده میشود و از html - url - EScape-js - Base64 - string و ... پشتیبانی میکند.
- Encryption & Decryption : جهت Encrypt و Decrypt انواع رشته استفاده میشود که از انکریپتورهای معروفی همچون AES - Rijndael - DES - SHA - TripleDES پشتیبانی میکند.
- Language Translation : یک دیکشنری Multi Language آنلاین در اختیار شما برای ترجمه متون قرار میدهد.
- C# & VB.Net Convertor : برای تبدیل کدهای C# به Vb و برعکس استفاده میشود و طبق تست هایی که روش به شخصه انجام دادم در اکثر موارد بدون خطا تا حدود 90 درصد تبدیلات رو به صورت موفق انجام میده ولی مانند سایر Convertorها با Lambda Expression کمی مشکل دارد.
- Xml & Json Browser : برای مشاهده و تبدیل Xml به Json و برعکس بسیار مفید است ..
- Linq Tester : برای تست کوئریهای Linq استفاده میشود . (برای استفاده از این امکان باید Roslyne روی سیستم شما نصب باشد)
- Database.Net
SQL Server 2000/2005/2008/2012/2014/Express/LocalDB SQL Server Compact 3.1/3.5/4.0 (*.sdf;*.*) SQL Azure 10/11 MS Access 97/2000/2002/2003 (*.mdb;*.mde;*.*), 2007/2010/2013 (*.accdb;*.accde;*.*) MS Excel 97/2000/2002/2003(*.xls;*.*), 2007/2010/2013 (*.xlsx;*.xlsm;*.xlsb;*.*) Firebird SuperServer/Embedded 1.5/2.0/2.1/2.5 (*.gdb;*.fdb;*.*) SQLite 3.x (*.db;*.db3;*.sqlite;*.*) MySQL 5.x, MariaDB 5.x/10.x PostgreSQL 8.x/9.x Oracle 10g/11g/12c IBM DB2 9.x/10.x IBM Informix 11.x/12.x Sybase ASE 15.x dBASE IV (*.dbf) Visual FoxPro (*.dbc) Data Sources (OleDB)(*.udl;*.*) ODBC DSN (Data Source Name)(*.dsn;*.*) OData (Open Data Protocol) v1/v2/v3/v4
- Resource.Net
سایر نرم افزارهای این تیم هم مانند نرم افزارهای معرفی شده بین کاربران محبوبیت زیادی کسب کرده اند که میتوانید برای کسب اطلاعات بیشتر و دانلود این نرم افزارها به وب سایت این تیم مراجعه فرمائید.
- Singleton
- Scoped
- Transient
Singleton (یگانه)
فقط و فقط یک شیء از سرویس ثبت شده با این طول عمر، در اولین درخواست ایجاد میشود و سپس در کل طول حیات برنامه، از همین شیء ایجاد شده، استفاده میگردد. به همین دلیل به آن «یگانه» یا Singleton میگویند. هر زمانیکه این سرویس در خواست داده میشود، DI Container، همان یک شیء را در اختیار درخواست دهنده قرار میدهد و این شیء، هیچگاه از بین نمیرود. به بیان دیگر، DI Container هیچگاه این شیء را از بین نمیبرد. شیء ساخته شده از سرویس ثبت شدهی با حالت Singleton، بین تمامی استفاده کنندگان، به صورت اشتراکی استفاده میشود. این طول عمر تقریبا مشابهی اشیاء ساخته شده توسط Singleton Pattern عمل میکند.
با توجه به مطالب گفته شده، ویژگیهای سرویسهای Singleton به شرح زیر هستند:
- در اولین درخواست به سرویس، یک نمونه از آن ساخته میشود و تا پایان برنامه در حافظه نگه داشته میشود.
- در سایر درخواستها، همان یک نمونهی ساخته شدهی از سرویس، ارائه داده میشود.
- به علت موجود بودن در حافظه، معمولا دسترسی به آنها و عملکرد آنها سریعتر است.
- بار کاری بر روی Garbage Collector فریمورک را کاهش میدهند.
بنابراین در هنگام تعریف کردن یک سرویس به صورت Singleton باید نکات زیر را مد نظر قرار بدهید:
- باید سرویس مورد نظر Thread Safe باشد .
- نباید استفاده کنندهی از این سرویس، امکان تغییر State آن را داشته باشد.
- اگر ساخت شیءای از یک سرویس، هزینهی زیادی را داشته باشد ، احتمالا Singleton کردن آن میتواند ایدهی خوبی باشد.
- شیء ساخته شدهی از این سرویس، تا زمان اجرای برنامه، بخشی از حافظهی برنامه را اشغال میکند. پس باید حجم اشغالی در حافظه را نیز مد نظر قرار داد.
- تعداد دفعات استفاده را در برابر مصرف حافظه در نظر بگیرید.
services.AddSingleton(services => new GuidProvider());
public HomeController(ILogger<HomeController> logger, IMessageServiceA messageService, LiteDbConfig liteDbConfig, GuidProvider guidHelper) { _logger = logger; _messageService = messageService; _messageService = new MessageServiceAA(); _guidHelper = guidHelper; }
حالا اگر برنامه
را اجرا کنیم، میبینید که با تازه
سازی صفحهی Home/Index ، همچنان Id، برابر با یک رشتهی یکسان
است. حتی اگر تب دیگری را در مرورگر باز کنیم و دوباره به این صفحه برویم، میبینیم
که Id برابر همان
رشتهی قبلی است و دلیل این موضوع، ثبت
سرویس Guid Service به صورت Singleton است.
Scoped ( محدود شده )
به ازای هر درخواست (در اینجا معمولا درخواستهای Http مد نظر است) یک نمونه از این سرویس ساخته میشود و در طول حیات این درخواست، DI Container به هر کلاسی که به این سرویس نیاز دارد، همان یک نمونه را برگشت میدهد و این نمونه در کل طول اجرای این درخواست، بین تمامی سرویس گیرندگان، یکسان است. هر زمانی، درخواست به پایان برسد، نمونهی ساخته شده از سرویس، Disposed میگردد و GC میتواند آن را از بین ببرد.
معمولا سرویسهای اتصال به پایگاه دادهها و کار بر روی آنها که شامل خواندن، نوشتن، ویرایش، حذف میشوند را با طول حیات Scoped ، درون DI Container ثبت میکنند . EF Core به صورت پیش فرض ، Db Context را به صورت Scoped ثبت میکند.
سرویسهای Scoped در محدودهی درخواست، مانند Singleton عمل میکنند و شیء ساخته شده و وضعیت آن در بین تمامی سرویسهایی که به آن نیاز دارند، مشترک است. بنابراین باید به این نکته در هنگام تعریف سرویس به صورت Scoped ، توجه داشته باشید.
تمام Middleware های ASP.NET Core هم فقط همان نمونهی ایجاد شده از سرویس Scoped را در طی اجرای یک درخواست خاص، میگیرند.
هر سرویسی که به سرویسهای Scoped نیاز دارد، یا باید به صورت Transient و یا باید به صورت Scoped ثبت شود، تا مانع از این شویم که شیء ساخته شده، فراتر از طول حیات موردنظرمان، در حافظه بماند و از آن استفاده شود .
برای ثبت یک سرویس
به صورت Scoped میتوانیم از متدهای توسعهای با نام AddScoped() با سربارهای
مختلف بر روی IServiceCollection استفاده کنیم. در اینجا از نسخهای که دو
پارامتر جنریک را میگیرد، برای ثبت یک سرویس به صورت Scoped استفاده میکنیم:
services.AddScoped<IMessageServiceB, MessageServiceBA>();
می توانیم سرویس GuidProvider را به جای Signleton ، به صورت Scoped ثبت کنیم:
services.AddScoped(services => new GuidProvider());
Transient (گذرا)
به ازای هر درخواست دهندهی جدید، یک نمونهی جدید از سرویس، توسط DI Container ساخته میشود و در اختیار آن قرار میگیرد.
سرویسهایی را به این صورت ثبت کنید که:
- نیاز به Thread Safe بودن داشته باشند.
- نمی توانید طول عمر سرویس را حدس بزنید.
سرویسهای Transient ، کارآیی پائینتری دارند و سربار عملکردی زیادی بر روی Garbage Collector می گذارند؛ ولی به علت اینکه به ازای هر واکشی، یک نمونهی جدید از آنها ساخته میشود و State بین این اشیاء به اشتراک گذاشته نمیشود، امنیت بیشتری دارند و درک و خطایابی آنها سادهتر است.
برای ثبت سرویسهای Transient از متد توسعهای AddTransient() استفاده میکنیم. سربارهای این متد مانند سربارهای متدهای AddSingleton() و AddScoped() است:
services.AddTransient<IMessageServiceC, MessageServiceCA>();
وابستگیهای محصور شده
یک سرویس نباید وابستهی به سرویسی باشد که طول حیاتی کمتر از طول حیات خودش را دارد.
برای مثال اگر درون سرویسی با طول حیات Singleton، از یک سرویس با طول حیات Transient استفاده کنیم، اینکار باعث میشود که یک نمونه از سرویس Transient در طول حیات برنامه، همیشه درون حافظه بماند و این ممکن است باعث خطاهای عجیبی در هنگام اجرا شود که معمولا خطایابی و رفع آنها مشکل است.
اثرات جانبی وابستگیهای محصور شده:
- به اشتراک گذاری تصادفی وضعیت یک شیء بین Thread ها درون سرویسهایی که Thread Safe نیستند.
- اشیاء، بیش از زمان پیش بینی شدهی برایشان، درون حافظه باقی میمانند.
سرویسهای Transient میتوانند به سرویسهایی با طول حیات زیر وابستگی داشته باشند:
- Transient
- Scoped
- Singleton
سرویسهای Scoped میتوانند به سرویسهایی با طول حیات زیر وابستگی داشته باشند:
- Transient
- Scoped
سرویسهای Singleton میتوانند به سرویس هایی با طول حیات زیر وابستگی داشته باشند:
Singleton
میتوانید از جدول زیر به عنوان راهنمای خلاصه شدهی برای استفادهی امن از سرویسها درون یکدیگر بهره ببرید:
Scope Validation
این قابلیت که به صورت پیش
فرض در حالت توسعهی برنامههای ASP.NET Core فعال است، در زمان شروع برنامه و در Startup ، بررسی میکند که سرویسها، وابستگی
به سرویسهایی با طول حیاتی مناسب، داشته باشند.
var image = document.createElement("img"); image.setAttribute("src", "logo.png"); React.createElement("img", { src : "logo.png" });
Virtual DOM
تفاوت در ساخت تگهای HTML به صورت مجازی بین JavaScript و React این است که React وضعیت تگهایی را که میسازد دنبال میکند. برای مثال فرض کنید نام سه محصول را در یک تگ < ul > نشان دادهایم. React وضعیت اصلی این تگ را که به مرورگر فرستاده، در حافظه دارد و همچنین در اثر تغییر منبع دادهای که برای < ul > مشخص کردهایم (که میتواند ورود اطلاعات به صورت Ajax باشد (مثلا اضافه شدن یک محصول جدید)) وضعیت جدیدی را برای تگ < ul > در حافظه ایجاد میکند. با وجود دو وضعیت برای یک تگ در حافظه، React میتواند تفاوت بین آنها را تشخیص داده و تگ را به روز کند. به این حالت عملکرد React ، اصطلاحا Virtual DOM میگویند.
React رابط کاربری را به صورت یک مدل میبیند و این مدل را با توجه به وضعیت اصلی آن در حافظه دوباره میسازد. برای React مهم نیست که ماهیت تغییر چیست. فقط وضعیتها را مثل دو عکس میبیند و میفهمد که آیا چیزی عوض شدهاست یا نه. دیالوگ React با مرورگر اینطور است: ای تگ < ul > این لیست را نشان بده (لیستی با سه محصول)، و بعد میگوید: ای تگ < ul > این لیست را نشان بده (لیستی با چهار محصول)!
کامپوننتهای React
<a href = “http://google.com”> <img src=”google.png”/> </a> // Components <clickableimage/> <linkimage/>
در کد بالا، بخش اول واضح است. عکسی که قابلیت کلیک شدن را دارد. حال فرض کنید یکی از کامپوننتهای <clickableimage/> یا <linkimage/>، همان تصویر قابل کلیک را ایجاد کنند. با نام گذاری واضح کامپوننتها، خوانایی برنامه بهتر میشود. یعنی میدانیم هر کامپوننت چه کاری را برای ما انجام میدهد. با این تصور که اگر تگهای زیاد و طولانی را در بخش رابط کاربری داریم، ارزش استفاده از کامپوننتهای React مشخص میشود.
قابلیت استفاده مجدد
در React کامپوننتها برای اساس توابع ساخته میشوند. یعنی وقتی یک کامپوننت را صدا بزنیم، در واقع یک تابع را اجرا میکنیم. در نتیجه کامپوننتها رفتار توابع را دارند؛ ورودی میگیرند و خروجی که یک DOM مجازی است را تحویل میدهند. اگر تابعی که مسئول ساخت کامپوننت است وابستگی به توابع یا متغیرهای بیرونی نداشته باشد، میتواند در جای دیگری از برنامه یا برنامهای دیگر مجددا استفاده شود. کد زیر نشان میدهد که چطور کامپوننتهای React ساخته میشوند.var ClickableImage = function(props) { return ( <a href={props.href}> <img src={props.src} /> </a> ); }; ReactDOM.render( <ClickableImage href="http://google.com" src="logo.png" />, document.getElementById("targetDivId"));
- Transient
- Scoped
- Singleton
- Constructor Injection
- Property Injection
- Method Injection
- Action & Handler Injection
Microsoft.AspNetCore.Mvc
public class AccountController : Controller { public IActionResult ConfirmEmail([FromServices] IEmailSender emailSender) { // emailSender.SendAsync(...); } }
public IActionResult About([FromServices] IDateTime dateTime) { ViewData["Message"] = $"Current server time: {dateTime.Now}"; return View(); }
[HttpGet] public ProductModel GetProduct([FromServices] IProductModelRequestService productModelRequest) { return productModelRequest.Value; }