نظرات مطالب
الگوی طراحی Builder همراه با اصول Interface Segregation
اما سادگی در این طراحی بنظر گم میشه ، شی Person که در یک خط کد میشد ساخته بشه الان با چندین Interface و کلاس باید ساخته بشه که در کل هزینه پیاده سازی و نگهداری رو بالاتر میبره. در پروژه واقعی از این الگو استفاده شده؟
نظرات مطالب
EF Code First #12
«No Default Instance» یعنی در تنظیمات اولیه IoC Container مورد استفاده، برای اینترفیس خاصی، کلاس پیاده سازی کننده‌ای را تعریف نکرده‌اید. برای مشاهده بحث مشابهی در این مورد به نظرات مطلب «تزریق خودکار وابستگی‌ها در برنامه‌های ASP.NET MVC » مراجعه کنید.
نظرات مطالب
اجرای وظایف زمان بندی شده با Quartz.NET - قسمت اول
طراحی lock و مباحث همزمانی ( lock, mutex, semaphore ) و Threading را باید خودتان پیاده سازی کنید. DisallowConcurrentExecution یعنی یک وهله از یک کلاس خاص در زمان اجرا ایجاد شده و چندین وهله همزمان از آن ایجاد نخواهد شد. روش دیگر اینکار استفاده از TriggerListener, JobListener or SchedulerListener است. یکی که تمام شد، بعدی شروع شود.
نظرات مطالب
EF Code First #12
شما محدود نیستید به چند متد اولیه‌ای که در اینترفیس Uow ذکر شده. یک متد با امضای اجرای SQL به آن اضافه کنید و پیاده سازی آن‌را در کلاس Context خود که از اینترفیس Uow مشتق می‌شود، انجام دهید (مانند this.Database الی آخر). بعد کلاس‌های استفاده کننده از Uow به آن دسترسی خواهند داشت.
نظرات مطالب
ModelBinder سفارشی در ASP.NET MVC
بله. یک کلاس مشتق شده از System.Web.Mvc.DefaultModelBinder ایجاد کنید. در آن متد BindProperty را override کرده و سپس اگر خاصیتی، مثلا خاصیت X بود (بر اساس مثلا یک ویژگی خاص که به آن انتساب داده شده)، آنگاه از Model binder سفارشی استفاده گردد.
یک نمونه پیاده سازی کامل آن:
MVC Property Binder 
نظرات مطالب
دریافت زمانبندی شده به روز رسانی‌های آنتی ویروس Symantec به کمک کتابخانه‌های Quartz.NET و Html Agility Pack
یه سئوال دارم که همیشه ذهنم رو مشغول کرده
مگه اینترفیس فقط امضا روال‌ها رو نداره؟ پس یک کلاس نیاز داره که بتونه اون متدها رو پیاده سازی کنه و ما ازش استفاده کنیم
غیر از اینه؟
پس در کد زیر
    IJobDetail job = JobBuilder.Create<HelloJob>()

مجبوریم از اینترفیس به عنوان متغیر استفاده کنیم؟
نظرات مطالب
EF Code First #12
بازم ببخشید آقای نصیری،
در اینصورت به پیاده سازی متد SaveChanges اینترفیس IUnitOfWork باید Overrides هم اضافه بشه که کامپایلر بدونه متد SaveChanges اینترفیس IUnitOfWork متد SaveChanges کلاس DbContext رو تحریف کرده،درسته؟
نظرات مطالب
اجرای وظایف زمان بندی شده با Quartz.NET - قسمت اول
System.Threading.Tasks.TaskScheduler، یک کلاس abstract هست. باید برای اون پیاده سازی صورت بگیره و به خودیه خود، کار خاصی انجام نمیده. برای اجرای وظایف به طور همزمان یا ایجاد یک صف از وظایف استفاده میشه، یا میشه با استفاده از اون، Thread جاری رو ذخیره کرد تا بعداً بشه در هنگام پایان یافتن کار یک Thread، به کنترل‌های UI از طریق اون دسترسی داشت.
در مبحث این مقاله جایی نداره.
مطالب
چگونه پروژه‌های Angular ی سبکی داشته باشیم - قسمت اول
یکی از عیب‌هایی که برنامه نویسان front-end و گاها بعضی از مدیران از Angular می‌گیرند، حجم زیاد صفحاتی است که با Angular کار می‌شود. در نتیجه‌ی جستجوی مشکل ذکر شده، با تعدادی پاسخ مشابه ^ و ^ روبرو می‌شویم که هیچ کدام روش صحیحی را برای رفع مشکل ذکر شده عنوان نکرده‌اند. در ادامه پروژه‌ی Angular ای را شروع می‌کنیم و حجم صفحات خروجی را مورد بررسی قرار می‌دهیم. سپس نحوه‌ی بهینه سازی و کم کردن حجم صفحات خروجی را بررسی می‌کنیم. 

برای شروع، CMD را در مسیر دلخواهی برای ساخت پروژه باز کرده  و ابتدا Angular CLI را توسط دستور زیر به آخرین نسخه‌ی موجود به‌روز رسانی می‌کنیم:
npm install -g @angular/cli
و سپس پروژه‌ی انگیولاری را  با دستور زیر می‌سازیم:
ng new HowToKeepAngularSizeSmall
پاسخ سوال ? Would you like to add Angular routing? (y/N)  را  y و scss را به عنوان فرمت stylesheet انتخاب می‌کنیم.
در ادامه پروژه را با استفاده از دستور زیر
ng serve --open --prod
اجرا می‌کنیم . سپس با استفاده از ابزار DevTools console از تب network، حجم فایل‌های لود شده را بررسی می‌کنیم:

حجم خروجی پروژه بعد از ساخت 222KB است.
حال برای آنکه پروژه‌ی جاری را به پروژه‌های واقعی نزدیک‌تر کنیم، بسته‌های npm زیر را به فایل package.json اضافه کرده و با دستور npm i بسته‌ها را نصب می‌کنیم.
"@agm/core": "^1.0.0-beta.5",
"@angular/flex-layout": "^7.0.0-beta.23",
"@angular/material": "^7.3.3",
"@angular/platform-browser": "~7.2.0",
"@asymmetrik/ngx-leaflet": "^5.0.1",
"@ngx-loading-bar/router": "1.3.1",
"@ngx-translate/core": "^11.0.1",
"@ngx-translate/http-loader": "^4.0.0",
"@progress/kendo-angular-buttons": "^4.3.3",
"@progress/kendo-angular-dateinputs": "^3.6.0",
"@progress/kendo-angular-dialog": "^3.10.1",
"@progress/kendo-angular-dropdowns": "^3.5.1",
"@progress/kendo-angular-excel-export": "^2.3.0",
"@progress/kendo-angular-grid": "^3.13.0",
"@progress/kendo-angular-inputs": "^4.2.0",
"@progress/kendo-angular-intl": "^1.7.0",
"@progress/kendo-angular-l10n": "^1.3.0",
"@progress/kendo-angular-layout": "^3.2.0",
"@progress/kendo-data-query": "^1.5.0",
"@progress/kendo-drawing": "^1.5.8",
"@progress/kendo-theme-default": "^3.3.1",
"@swimlane/ngx-datatable": "^14.0.0",
"angular-calendar": "0.23.7",
"angular-tree-component": "7.0.1",
"bootstrap": "^3.4.0",
"chart.js": "2.7.2",
"d3": "4.13.0",
"dragula": "3.7.2",
"hammerjs": "2.0.8",
"intl": "1.2.5",
"leaflet": "1.3.1",
"moment": "2.21.0",
"ng2-charts": "1.6.0",
"ng2-dragula": "1.5.0",
"ng2-file-upload": "1.3.0",
"ng2-validation": "4.2.0",
"ngx-perfect-scrollbar": "5.3.5",
"ngx-quill": "2.2.0",
"screenfull": "3.3.2",
"font-awesome": "^4.7.0",
"jalali-moment": "^3.3.1",
"jquery": "^3.3.1",
"ng-snotify": "^4.3.1",
"normalize.css": "^8.0.1",
و خطوط زیر را به styles.scss اضافه می‌کنیم:
@import "~bootstrap/dist/css/bootstrap.css";
@import "~@progress/kendo-theme-default/scss/all";
@import '@angular/material/prebuilt-themes/pink-bluegrey.css';
@import '~perfect-scrollbar/css/perfect-scrollbar.css';
@import "~ng-snotify/styles/material";
و قسمت scripts زیر را به فایل angular.json اضافه می‌کنیم:
"scripts": [
              "node_modules/jquery/dist/jquery.js",
              "node_modules/bootstrap/dist/js/bootstrap.min.js",
              "node_modules/hammerjs/hammer.min.js"
            ],
و فایل app.module.ts را نیز به صورت زیر تغییر می‌دهیم:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';


// Import Material
import {
  MatFormFieldModule, MatInputModule,
  MatButtonModule, MatButtonToggleModule,
  MatDialogModule, MatIconModule,
  MatSelectModule, MatToolbarModule,
  MatDatepickerModule,
  DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE, MatTableModule, MatCheckboxModule, MatRadioModule, MatCardModule, fadeInContent,
  MatListModule, MatProgressBarModule, MatTabsModule,
  MatSidenavModule,
  MatSlideToggleModule,
  MatMenuModule
} from '@angular/material';



// Import kendo angular ui
import { ButtonsModule } from '@progress/kendo-angular-buttons';
import { GridModule, ExcelModule } from '@progress/kendo-angular-grid';
import { DropDownsModule } from '@progress/kendo-angular-dropdowns';
import { InputsModule } from '@progress/kendo-angular-inputs';
import { DateInputsModule } from '@progress/kendo-angular-dateinputs';
import { DialogsModule } from '@progress/kendo-angular-dialog';
import { RTL } from '@progress/kendo-angular-l10n';
import { LayoutModule } from '@progress/kendo-angular-layout';
import { WindowService, WindowRef, WindowCloseResult, DialogService, DialogRef, DialogCloseResult } from '@progress/kendo-angular-dialog';

import { SnotifyModule, SnotifyService, SnotifyPosition, SnotifyToastConfig, ToastDefaults } from 'ng-snotify';


import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,

    // material 
    MatSidenavModule,
    MatSlideToggleModule,
    MatInputModule,
    MatFormFieldModule,
    MatButtonModule, MatButtonToggleModule,
    MatDialogModule, MatIconModule,
    MatSelectModule, MatToolbarModule,
    MatDatepickerModule,
    MatCheckboxModule,
    MatRadioModule,
    MatCardModule,
    MatMenuModule,
    MatListModule,
    MatProgressBarModule,
    MatTabsModule,


    // kendo-angular
    ButtonsModule,
    GridModule,
    ExcelModule,
    DropDownsModule,
    InputsModule,
    DateInputsModule,
    DialogsModule,
    LayoutModule,

    SnotifyModule,


  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

بدون اینکه component جدیدی را به پروژه‌ی جاری اضافه کنیم، پروژه را با دستور ng serve --open --prod  اجرا کرده و خروجی را بررسی می‌کنیم:

همانطور که می‌بینید بدون افزودن کامپوننت جدیدی، حجم خروجی از 222KB به 582KB رسیده‌است. معمولا در هر پروژه نیاز به تعدادی دایرکتیو و سرویس پایه نیز می‌باشد که کم کم به حجم خروجی صفحات می‌افزاید. در نظر بگیرید که هنوز هیچ قالب خاصی برای صفحه مورد نظرمان استفاده نشده و به حجم 582KB رسیده‌ایم. برای نمونه می‌توانیم سری به سایت madewithangular.com بزنیم و حجم خروجی تعدادی از سایت‌های نوشته شده‌ی با انگیولار را بررسی کنیم. سایت‌های زیر خروجی بالای 1.5MB دارند. همچنین سایتی را که خودم تقریبا یک سال پیش شروع کرده بودم، حجم خروجی آن  2.7MB است:

دلیل بالا رفتن حجم خروجی، اضافه شدن فایل‌های JavaScript و style-sheet به bundle اصلی پروژه است. برای مثال حجم فایل main.js را در نمونه‌های ذکر شده بررسی کنید. 

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

مطالب
آشنایی با الگوی طراحی Template Method
سناریویی وجود دارد که در آن شما می‌خواهید تنها یک کار را انجام دهید، ولی برای انجام آن n روش وجود دارد. برای مثال قصد مرتب سازی دارید و برای اینکار روش‌های مختلفی وجود دارند. برای حل این مساله پیشتر از الگوی طراحی استراتژی استفاده نمودیم.(مطالعه بیشتر در مورد الگوی طراحی استراتژی)
حال به سناریویی برخورد کردیم که بصورت زیر است:
می‌خواهیم یک کار را انجام دهیم ولی برای انجام این کار تنها برخی بخش‌های کار با هم متفاوت هستند. برای مثال قصد تولید گزارش و چاپ آن را داریم. در این سناریو خواندن اطلاعات و پردازش آن‌ها رخدادهایی ثابت هستند. ولی اگر بخواهیم گزارش را چاپ کنیم به مشکل می‌خوریم؛ چرا که چاپ گزارش به فرمت اکسل، فرمت و روش خود را دارد و چاپ به فرمت PDF شرایط خود را دارد.
در این سناریو دیگر الگوی طراحی استراتژی جواب نخواهد داد و نیاز داریم با یک الگوی طراحی جدید آشنا بشویم. این الگوی طراحی Template Method نام دارد.
در این الگو یک کلاس انتزاعی داریم به صورت زیر:
    public abstract class DataExporter
    {
        public void ReadData()
        {
            Console.WriteLine("Data is reading from SQL Server Database");
        }

        public void ProcessData()
        {
            Console.WriteLine("Data is processing...!");
        }

        public abstract void PrintData();

        public void GetReport()
        {
            ReadData();
            ProcessData();
            PrintData();
        }
    }
این کلاس abstract، یک متد بنام GetReport دارد که نحوه‌ی انجام کار را مشخص می‌کند. متدهای ReadData و ProcessData نشان می‌دهند که انجام این دو عمل همیشه ثابت هستند (منظور در این سناریو همیشه ثابت هستند). متد PrintData همانطور که مشاهده می‌شود بصورت انتزاعی تعریف شده است، چرا که چاپ عملی است که در هر فرمت دارای خروجی متفاوتی می‌باشد.
لذا در ادامه داریم:
    public class ExcelExporter : DataExporter
    {
        public override void PrintData()
        {
            Console.WriteLine("Data exported to Microsoft Excel!");
        }
    }

    public class PDFExporter : DataExporter
    {
        public override void PrintData()
        {
            Console.WriteLine("Data exported to PDF!");
        }
    }
کلاس ExcelExporter برای چاپ به فرمت اکسل می‌باشد. همانطور که مشاهده می‌شود این کلاس از کلاس انتزاعی DataExporter ارث بری کرده است. این بدین معنا است که کلاس ExcelExporter کارهای ReadData و ProcessData را از کلاس پدر خود می‌گیرد و در ادامه نحوه‌ی چاپ مختص به خود را پیاده می‌کند. همین توضیحات در مورد PDFExporter نیز صادق است.
حال برای استفاده‌ی از این کدها داریم:
            DataExporter dataExporter = new ExcelExporter();
            dataExporter.GetReport();
            Console.WriteLine("****************************");
            dataExporter = new PDFExporter();
            dataExporter.GetReport();
شما شاید بخواهید متدهای ReadData و ExportData و ProcessData را با سطح دسترسی متفاوتی از public تعریف نمایید که در این مقاله به این دلیل که خارج از بحث بود به آنها اشاره نشد و بصورت پیش فرض public در نظر گرفته شد.