مطالب
بخش دوم - بررسی امکانات (کلاس ها و متدهای) کتابخانه Gridify
در بخش قبل، به چند نمونه کلی از امکانات کتابخانه Gridify اشاره کردیم. در این مقاله به معرفی کلاس‌ها و متدهای این کتابخانه میپردازیم.

GridifyQuery
از این کلاس برای اعمال تنظیمات مورد نیاز در متدهای ارائه شده توسط Gridify استفاده میشود. در ادامه به خصیصه (پراپرتی)های این کلاس میپردازیم.
  • Filter : یک پراپرتی از نوع string است که درصورت مقداردهی آن، بر روی لیست خروجی ما عملیات فیلترینگ اعمال میشود. مثال :
Filter = "Name==Ali,Age>>10";
  • SortBy : یک پراپرتی از نوع string است که درصورت مقداردهی آن، بر روی لیست خروجی ما عملیات چیدمان یا سورتینگ با استفاده از نام فیلد انجام میشود. مثال : 
SortBy = "Age";
  • IsSortAsc: یک پراپرتی از نوع bool است که مشخص کننده چیدمان به صورت نزولی و یا صعودی است.
  • Page : یک پراپرتی از نوع عددی short است. از این پراپرتی برای عملیات Pagination یا صفحه بندی استفاده میشود که مشخص کننده شماره صفحه درخواستی است.
  • PageSize : یک پراپرتی از نوع عددی int است که برای مشخص کردن تعداد رکورد در هر صفحه استفاده میشود.
وارد کردن این اطلاعات هنگام استفاده از کتابخانه Gridify الزامی نیست؛ به همین جهت تنها در صورت مقداردهی، از این اطلاعات استفاده میشود. درصورتیکه هیچ اطلاعاتی در این پراپرتی‌ها وجود نداشته باشد، به صورت پیش فرض توسط Gridify نادیده گرفته میشود. البته استثنایی برای اکستنشن متد Gridify و GridifyAsync وجود دارد، به دلیل اینکه خروجی این دو متد یک کلاس <Paging<T است. در صورت اینکه مقداری برای پراپرتی‌های Page و PageSize وارد نشده باشد، به صورت پیش فرض اطلاعات Page 1 با DefaultPageSize را بازمیگرداند که مقدار پیش فرض آن 10 میباشد. با استفاده از تغییر فیلد استاتیک DefaultPageSize میتوان این عدد نیز را تغییر داد.


متد‌های الحاقی یا IQueryable  Extensions 
برای استفاده از کتابخانه Gridify نیازی به ساخت هیچ کلاسی نیست و صرفا امکانات اینترفیس IQueryable را گسترش میدهد.
 ApplyFiltering  از این متد برای اعمال فیلترینگ روی یک IQueryable استفاده میشود. این متد یک رشته متنی (string) ویا یک GridifyQuery دریافت کرده و پس از اعمال فیلترینگ یک IQueryable بازمیگرداند.
 ApplyOrdering  از این متد برای اعمال چیدمان یا Sorting روی یک IQueryable استفاده میشود. پس از اعمال چیدمان، یک IQueryable را بازمیگرداند.
 ApplyPaging از این متد برای اعمال صفحه بندی (Pagination) استفاده میشود. پس از اعمال صفحه بندی یک IQueryable را بازمیگرداند. 
 ApplyOrderingAndPaging   از این متد برای اعمال همزمان چیدمان و صفحه بندی استفاده میشود که یک IQueryable را باز میگرداند. 
ApplyFilterAndOrdering  از این متد برای اعمال همزمان فیلترینگ و چیدمان استفاده میشود که یک IQueryalbe را باز میگرداند.
 ApplyEverything   از این متد برای اعمال عملیات صفحه بندی، چیدمان و فیلترینگ استفاده میشود که یک IQueryable را باز میگرداند.
 GridifyQueryable   این متد مشابه ApplyEverything است که مقدار یک <QueryablePaging<T را برمیگرداند و دارای یک خصیصه اضافی TotalItems است که در عملیات صفحه بندی عموما نیاز داریم. (تعداد کل رکورد‌های موجود در پایگاه داده، با توجه به فیلتر اعمال شده)
 Gridify  متدهای قبلی فقط به query موجود ما یکسری شرط را اضافه میکردند. ولی مسئولیت اجرای query به عهده ما بود. (مثلا با استفاده از ToList.). متد Gridify تمامی شرط‌ها را باتوجه به GridifyQuery دریافتی اعمال کرده، سپس اطلاعات را بارگذاری کرده و یک <Paging<T را بازمیگرداند که کاملا قابل استفاده و بهینه شده برای دیتاگرید‌ها میباشد.


متد‌های الحاقی GridifyQuery:
 GetFilteringExpression   این متد expression معادل فیلتر string نوشته شده شما را برمیگرداند که میتوانید از آن به طور مثال در متد Where در Linq استفاده نمایید. 
 GetOrderingExpression   این متد expression انتخاب فیلد برای Orderby و OrderByDescending را باتوجه به مقدار وارد شده در فیلد SortBy بازمیگرداند.

Filtering Operators:
با علائم پشتیبانی شده در Gridify برای اعمال فیلترینگ در زیر آشنا میشویم.

همانطور که در تصویر بالا مشاهده میکنید، برای اعمال فیلترینگ‌های پیچیده میتوانیم از چهار اپراتور , | ( )  استفاده کنیم. به همین جهت اگر نیاز داشتید که در مقدار جستجوی خود از این علائم استفاده کنید، باید قبل از هرکدام از آنها، علامت \ را اضافه کنید. 

 مثال رج‌اکس escape character در JavaScript  : 

let esc = (v) => v.replace(/([(),|])/g, '\\$1')

مثال #‍C : 

var value = "(test,test2)";
var esc = Regex.Replace(value, "([(),|])", "\\$1" ); // esc = \(test\,test2\)  

در بخش بعد با امکانات Mapper توکار Gridify و شخصی سازی آن آشنا خواهیم شد.

اشتراک‌ها
دوره ساخت قدم به قدم یک برنامه‌ی NET MAUI.

In this video we perform a full step by step build of a .NET MAUI App that we test on both Windows and Android. The app interacts with a separate .NET 6 API that we also build step by step.

Level: Beginner

⏲️ Time Codes ⏲️

Theory

- 0:48 Welcome
- 03:13 App demo
- 06:07 Course overview
- 09:14 Ingedients
- 10:10 What is .NET MAUI?
- 12:48 How MAUI works
- 15:14 MAUI project anatomy
- 19:47 MAUI App start up sequence
- 22:29 UI Conepts
- 28:21 XAML vs C#
- 30:29 Solution Architecture
- 31:41 Application Architecture


API Build

- 35:31 API Project Set up
- 42:41 API Model definition
- 44:47 API Db Context
- 47:13 Connection String
- 52:19 Migrations
- 56:31 API Read Endpoint
- 1:01:58 API Create Endpoint
- 1:08:15 API Update Endpoint
- 1:12:57 API Delete Endpoint

MAUI App Build

- 1:17:21 MAUI App Project Set up
- 1:21:00 Android Device Manager
- 1:25:08 MAUI Model definition
- 1:31:16 Data Service Interface
- 1:35:40 Data Service Implementation
- 1:47:27 Data Service Read Method
- 1:53:34 Data Service Create Method
- 1:58:48 Data Service Delete Method
- 2:01:53 Data Service Update Method
- 2:05:41 Android environment config
- 2:11:00 Architecture check point
- 2:11:54 Register MainPage for DI
- 2:14:13 MainPage code-behind
- 2:21:03 MainPage XAML Layout
- 2:30:19 Re-work MainPage layout
- 2:35:12 Add another page (ManagePage)
- 2:38:01 Adding a Route
- 2:30:01 Regiter ManagePage for DI
- 2:40:29 Complete MainPage code-behind
- 2:45:12 ManagePage code-behind
- 2:51:16 QueryProperty
- 2:57:34 ManagePage XMAL
- 3:07:56 Run on Windows
- 3:09:30 Re-work ManagePage layout
- 3:16:26 Using HttpClientFactory

Outro

- 3:21:02 Wrap up and thanks
- 3:21:31 Supporter Credits 

دوره ساخت قدم به قدم یک برنامه‌ی NET MAUI.
نظرات مطالب
الگوی استراتژی - Strategy Pattern
در کلاس abstract نیز می‌توان از پیاده سازی پیشفرض استفاده کرد . یکی از تفاوتهای کلاس abstract با Interface همین ویژگی است که سبب ورژن پذیری آن شده است.
مطالب
خواندنی‌های 29 تیر
نظرات مطالب
آشنایی با NHibernate - قسمت هشتم
با سلام،
فرض کنید در Table CoursesToStudents فیلدی به نام IsApproved را می خواهیم داشته باشیم، در اینصورت کلاس های نگاشت به چه صورت خواهد بود؟ در کدام کلاس نگاشت پیاده سازی می شود؟ اگر کلاس جداگانه ایی تعریف کنیم ایا باز هم رابطه ManyToMany برقرار خواهد بود؟

با تشکر
نظرات مطالب
OpenCVSharp #5
سلام؛ ممنون از مطلب خوبتون. من از کتابخانه‌های opncv و emgu برای خوندن تصویر از وب کم و پردازش تصویر استفاده میکنم. مشکل من سرعت پایین برنامه در رزولوشن بالای وب کم است هر چه رزولوشن بالاتر میره سرعت برنامه من کمتر میشه. مثلا تو یه سیستم corei7 با ram 8 gig من 61 درصد استفاده از cpu دارم و فیلم نمایش داده شده در برنامه از محیط واقعی عقب‌تر است. من در رویداد Application.Idle   فرم این کد را قرار دادم:
 public void Application_Idle(object sender, EventArgs e) 
        {
            if (_capture != null)
            {
                try
                {
                    frame = _capture.QueryFrame();
                    Pic.Image = frame.ToBitmap();
                    //frame.ToBitmap(dst: (Bitmap)Pic.Image);
                }
                catch (NullReferenceException excpt)
                {
                    MessageBox.Show(excpt.Message);// you can also show any suitable message
                }
            }
        }
شما فرمودید برای به حداقل رسانی به روز رسانی‌های بعدی picture box بهتر است از متد ToBitmap به شکل زیر کمک گرفت: 
iplImage.ToBitmap(dst: (Bitmap)pictureBox.Image);
ولی dst رو فرم نمیشناسه و اینکه آیا رویداد idle رویداد مناسبی برای این کار هست؟ نظرتون درباره سرعت پایین برنامه من چیه؟
نظرات مطالب
CheckBoxList در ASP.NET MVC
- کد کاملت باید باشه تا بتونم دیباگش کنم. این توضیحات رو جایی ارسال کنید، تصور نکنید که یک نفر مثلا یک ساعتی سعی در بازسازی مثال شما خواهد کرد. بعد سعی می‌کند تا خطای شما را به نحوی باز تولید کند و بعد هم مثلا یک مقاله جهت توضیح جزئیات آن در نصف روز منتشر می‌کند. این امر هیچ وقت رخ نخواهد داد. برای پاسخ دادن به یک سؤال، سرعت بازسازی آن مهم است.
- اگر نال دریافت می‌کنی ممکن است اطلاعات شما در یک فرم صحیح که به کنترلر اشاره می‌کند قرار ندارد یا حتی ممکن است نام‌های دیگری در سمت کاربر رندر شده باشند. هر دو مورد را با استفاده از نکات مطلب «نحوه استفاده از افزونه Firebug برای دیباگ برنامه‌های ASP.NET مبتنی بر jQuery » می‌توانید بررسی کنید. به این ترتیب مشخص میشه اصلا چه اطلاعاتی در برگه شبکه این افزونه زمان ارسال به سرور لاگ شده. این را بررسی کنید و سپس با ساختار داده کنترلر خودتون مقایسه‌اش کنید.
به صورت خلاصه، برگه network افزونه فایرباگ را در حین ارسال اطلاعات به سرور بررسی کنید. ساختار اطلاعات آن چیست؟ آیا تطابقی با پارامترهای کنترلر شما دارد یا خیر؟ مثلا من در مثال فوق نوشتم result. این مورد به این معنا نیست که خروجی نهایی HTML کار شما هم حتما result نام دارد (خصوصا اگر خودکار تولید می‌شود). بسته به نام واقعی عناصر انتخابی، نام این پارامتر متغیر خواهد بود. اما اصول نهایی یکی است.
- ضمنا روش دوم یافتن نام واقعی پارامترهای ارسالی، استفاده از روش قدیمی Request.Form در یک اکشن متد هست. این خاصیت دریافتی را دیباگ کنید تا به نام‌های واقعی برسید.
مطالب
تزریق وابستگی‌ها در ASP.NET Core - بخش 1 - مقدمه
مقدمه

زمانیکه یک برنامه را بر پایه‌ی شیء گرایی طراحی می‌کنید و می‌نویسید، به صورت معمول جریان وابستگی‌ها در برنامه‌ی شما به صورت زیر است:


 
در این حالت برای کامپایل شدن برنامه نیاز است که فرآیند کامپایل از دورترین کلاس و متد شروع شود. همانطور که می‌بینید در اینجا هر کلاس به تمام زیر کلاس‌های خود وابسته است و هر تغییر در هر کدام از کلاس‌های خدمتگزار می‌تواند تاثیرات مستقیمی بر روی سایر کلاس‌ها داشته باشد. در واقع جریان کنترل برنامه‌ی ما بجای اینکه در اختیار کلاس‌های سیاست گذار ( کلاس‌های بالایی در شکل) باشد، به دست کلاس‌های خدمتگزار افتاده است.  این قضیه باعث درهم تنیدگی و جفت شدگی کدها و کلاس‌ها به یکدیگر می‌شود که مشکل‌زاست و امکان نگهداری، تغییرات و توسعه‌ی برنامه را به شدت کاهش می‌دهد.

به عبارت دیگر در طراحی ساخت یافته، کلاس‌های سطح بالا، به کلاس‌های سطح پایین وابسته‌اند. این مسئله دو مشکل را ایجاد می‌کند:
  1. هر تغییری در کلاس‌های سطح پایین ممکن است باعث ایجاد اشکالی در کلاس‌های سطح بالا گردد.
  2. استفاده‌ی مجدد از کلاس‌های سطح بالا در جاهای دیگر مشکل است؛ زیرا وابستگی مستقیمی به کلاس‌های سطح پایین دارند.

اصل معکوس سازی / وارونگی وابستگی‌ها Dependency Inversion Principle
 
یکی از اصول پنجگانه‌ی طراحی برنامه‌های شیء گرا  که با نام اصول SOLID  شناخته می‌شوند، اصل «وارونگی وابستگی‌ها» است که روشی برای مشکل جفت شدگی و وابستگی کلاس‌ها به یکدیگر را به صورت تئوری ارائه می‌دهد.

 اصل وارونگی وابستگی‌ها بیان می‌کند:
  •   ماژول‌های (کلاس‌های) سطح بالا نباید به ماژولهای (کلاس‌های) سطح پایین وابسته باشند و هر دو باید به انتزاعات وابسته باشند (برای مثال interface‌ها).
  •   انتزاعات نباید وابسته به جزئیات باشند؛ بلکه جزئیات (پیاده سازی) باید وابسته به انتزاعات باشند.

بر اساس این اصل، ما باید در سطوح بالا سیاست گذاری‌ها و انتزاعات را در قالب interface‌ها تعریف کرده و کلاس‌های سطح بالای خود را بر همین اساس پیاده سازی کنیم و در سطوح پائین‌تر، پیاده سازی‌هایی را بر اساس انتزاعات و سیاست گذاری‌های سطوح بالاتر، انجام دهیم.

در شکل زیر، حالت عادی جریان کنترل را می‌بینید .
 


همانطور که می‌بینید، کلاس M برای اجرا، وابسته به کلاس N و متد F در درون آن است. در اینجا ما با استفاده از اینترفیس‌ها می‌توانیم جریان کنترل را معکوس یا وارونه کنیم که به این عمل «وارونگی کنترل یا Inversion of Control» می‌گویند.


 
شیء گرایی در واقع در مورد نحوه‌ی جریان کنترل است. در اینجا اینترفیس‌ها به ما کنترل کاملی را بر جریان کنترل (Flow of control) می‌دهند که با استفاده از این امکان می‌توانیم از نوشتن کدهای جفت شده، شکننده و کلاس‌هایی یکبار مصرف، بپرهیزیم.


الگوی Dependency Injection 
تزریق وابستگی یا Dependency Injection، یک الگوی طراحی است که از آن برای طراحی و پیاده سازی IoC Container‌ها استفاده می‌شود. این الگو به ما اجازه می‌دهد که اشیاء وابسته را خارج از کلاس بسازیم و آنها را به طریقی دیگر به کلاس، جهت استفاده ارائه دهیم. به‌وسیله‌ی DI ما ساخت و اتصال اشیاء وابسته به کلاس را از تعریف آن خارج می‌کنیم.

الگوی تزریق وابستگی 3 نوع کلاس را درگیر می‌کند:
  •  کلاس کلاینت / Client Class : کلاس کلاینت (کلاس وابسته) کلاسی است که به کلاس سرویس وابسته است .
  • کلاس سرویس  /  Service Class :  کلاس سرویس (وابستگی) کلاسی است که یک سرویس را به کلاس کلاینت ارائه می‌دهد.
  •  کلاس تزریق کننده / Injector Class  :  کلاس تزریق کننده، نمونه‌ای از کلاس سرویس را ساخته و به کلاس کلاینت، تزریق می‌کند.

شکل زیر وابستگی بین کلاس‌ها را شرح می‌دهد:

 
همانطور که می‌بینید، کلاس Injector، نمونه‌ای از کلاس سرویس را می‌سازد و آن را به نمونه‌ای از کلاس Client تزریق می‌کند. با این کار، DI، وظیفه‌ی ساخت یک نمونه از کلاس Service را از درون کلاس Client جدا می‌کند.

انواع تزریقات وابستگی‌ها:
به صورت کلی به سه روش و در سه مکان، امکان تزریق وابستگی کلاس سرویس، درون کلاس کلاینت وجود دارد:
  •   تزریق درون سازنده / Constructor Injection  : در تزریق درون سازنده، در سازنده‌ی کلاس کلاینت، لیستی از سرویس‌های مورد نیاز کلاس، که کلاس، برای عملکرد خود به آن‌ها «وابسته» است، ثبت می‌شوند و کلاس Injector، سرویس (وابستگی) مورد نظر را درون سازنده‌ی کلاس Client ارائه می‌دهد.
  •   تزریق درون Property  کلاس / Property Injection : در این حالت که همچنین با نام (Setter Injection) هم شناخته می‌شود، تزریق کننده، وابستگی را به وسیله‌ی یک Property عمومی کلاس کلاینت ارائه می‌دهد.
  •  تزریق درون متد / Method Injection  : در این حالت، خود کلاس کلاینت، یک پیاده سازی از یک interface را ارائه می‌کند که درون آن متدهایی برای ارائه‌ی وابستگی‌ها به کلاینت تعریف شده‌اند. در این وضعیت، تزریق کننده از این اینترفیس برای ارائه‌ی وابستگی‌ها به کلاینت درون متدها، استفاده می‌کند. 

هر کدام از روش‌های فوق مزایا و معایب خود را دارند، ولی در NET Core. بیشتر از «تزریق درون سازنده» استفاده می‌شود. در صورت لزوم می‌توانید از اینجا نمونه‌هایی از تزریق وابستگی را به هر کدام از سه روش بالا، مشاهده کنید.

Inversion of Control Container
در واژگان فنی مهندسی نرم افزار، Container (محفظه)  به جزیی از برنامه گفته می‌شود که می‌تواند اجزای دیگر برنامه را در بر بگیرد.  IoC Container ‌ها در واقع فریم ورک‌ها/چارچوب‌ها یا کتابخانه‌های برنامه نویسی هستند که ما در آنها می‌توانیم اشیاء مختلف را به سبک‌های خاصی تعریف و ثبت کنیم و در مواقع لزوم آنها را واکشی و به کلاس‌ها تزریق کنیم. معمولا  IoC Container‌ها لیستی از اشیاء هستند که در آن اینترفیس‌ها و پیاده سازی‌های مربوط به هر کدام از آن‌ها ثبت می‌شوند. درون IoC Container برای پیاده سازی اصل وارونگی وابستگی‌ها، معمولا از یکی از دو الگوی زیر استفاده می‌کنند (گاها هم دو الگو را با هم پیاده سازی می‌کنند) :
  •  Dependency Injection 
  • Service Locator

تمرکز اصلی ما در این نوشتار بر روی DI Container هاست. فرق Dependency Injection و Service Locator در این است که در DI، وابستگی‌ها توسط IoC Container از درون محفظه واکشی می‌شوند و به درون کد تزریق می‌شوند ولی در Service Locator در هر جایی از برنامه می‌توان با استفاده‌ی مستقیم از Container و با استفاده از متدهایی که به ما ارائه می‌دهد،  پرس و جو کرد (کوئری زد) و وابستگی مورد نظر را واکشی کرد.
در تزریق وابستگی، کلاس استفاده کننده از سرویس‌ها، درگیر نحوه‌ی واکشی و نمونه سازی از سرویس مورد نظر خود نمی‌شود و همه‌ی کار توسط DI Container انجام می‌گیرد. ولی در Service Locator باید سرویس مورد نظر، درون خود کلاس، مستقیما از Container دریافت و ساخته شود.
برای استفاده از Service Locator، تنها پیش نیاز، دسترسی به شیء Service Locator است.

به صورت کلی IoC Container ‌ها سه وظیفه‌ی اساسی را برعهده دارند:
  • ثبت سرویس درون خود
  •   ساخت نمونه‌های مورد نظر از سرویس‌ها و ارائه دادن آن‌ها به کلاس‌هایی که نیاز دارند.
  •  از بین بردن نمونه سرویس‌های ساخته شده (Dispose) کردن آن‌ها .

در ادامه با ساخت پروژه‌ای، اولین سرویس خودمان را درون Microsoft Dependency Injection Container یا به اختصار DI Container، ثبت کرده و آن را واکشی می‌کنیم.
نظرات اشتراک‌ها
معرفی کتابخانه‌ی DNTCaptcha.Core
با سلام؛ من از این کپچا برای سایتم استفاده می‌کردم تا اینکه هفته پیش مشکلی عجیبی پیش اومد هنگام استفاده از فایرفاکس فیلد کپچا در فرم خالی پست می‌شد اما با کروم بدون مشکل کار می‌کرد، با چند مرورگر فایرفاکس در اندروید، ویندوز 10 و ویندوز سرور 2012 تست کردم حتی تعدادی از کاربران سایت هم با ما تماس گرفتند و من پیشنهاد دادم که اون روز از برای لاگین از کروم استفاده کنند جالب اینجاست که آخرین ورژن فایرفاکس (64) این مشکل رو داشت اما ورژن قدیمی (52) مشکلی نداشت. ورژن سایت asp.net core 2.1 بود که به 2.2 ارتقا دادم و DNTCaptcha رو بروزرسانی کردم متاسفانه مشکل حل نشده و الان reCaptcha v3 نصبه که به اجبار دو اسکریپت به قالب اضافه شده ورژن sdk هم 2.2.103 هست. به نظرتون مشکل از چی می‌تونه باشه.
نظرات مطالب
اهمیت Controller های ساده در ASP.NET MVC
- تصور من اینست که معماری چندلایه یک stack است از لایه‌های مختلف با وظایف متفاوت. که پایین‌ترین سطح(دیتا سورس) تا بالاترین سطح(رابط کاربری) هست. در این بین بقیه اجزا مثل BL و غیره قرار میگیره. سوالم اینه که اگر بخواهیم یه الگوی نسبتا کلی ارائه بدیم این لایه‌ها چطور روی هم چیده میشه. 
- تجسم این لایه‌ها شاید از این لحاظ مهم باشه که یکی از مهمترین مفاهیم شی‌گرایی یعنی کپسوله‌سازی و Information hidding باعث تولید ایده‌ی چند لایه‌ای هست. و دانستن و اجرای درست اون خیلی کار توسعه را آسانتر میکنه.
- N-Tier یک معماری برای طراحی هست. ولی MVC یه الگوی طراحی. و این‌ها جایگزین که نه، بلکه به نوعی با هم‌پوشانی کار را اصولی‌تر میکند. همانطور که جناب نصیری در سری MVC اشاره‌ای موکد داشتند که Model در MVC در واقع همان ViewModel است. که این ViewModel از الگوی MVVM آمده.