سورس آن در اینجا
مطالب
آموزش WAF
دز طراحی پروژههای مقیاس بزرگ و البته به صورت ماژولار همیشه ساختار پروژه اهمیت به سزایی دارد. متاسفانه این مورد خیلی در طراحی پروژهها در نظر گرفته نمیشود و اغلب اوقات شاهد آن هستیم که یک پروژه بسیار بزرگ دقیقا به همان صورت پروژهای کوچک و کم اهمیتتر مدیریت و پیاده سازی میشود که این مورد هم مربوط به پروژههای تحت وب و هم پروژههای تحت ویندوز و WPF است. برای مدیریت پروژههای WPF و Silverlight در این پست به اختصار درباره PRISM بحث شد. مزایا و معایب آن بررسی و در طی این پست ها(^ و ^) مثال هایی را پیاده سازی کردیم. اما در این پست مفتخرم شما را با یکی دیگر از کتابخانههای مربوط به پیاده سازی مدل MVVM آشنا کنم. کتابخانه ای متن باز، بسیار سبک با کارایی بالا.
اما نکته ای که ذکر آن خالی از لطف نیست این است که قبلا از این کتابخانه در یک پروژه بزرگ و ماژولار WPF استفاده کردم و نتیجه مطلوب نیز حاصل شد.
معرفی:
WPF Application Framework یا به اختصار WAF کتابخانه کم حجم سبک و البته با کارایی عالی برای طراحی پروژههای ماژولار WPF در مقیاس بزرگ طراحی شده است که مدل پیاده سازی ان بر مبنای مدل MVVM و MVC است. شاید برایتان جالب باشد که این کتابخانه دقیقا مدل MVC را با مدل MVVM ترکیب کرده در نتیجه مفاهیم آن بسیار شبیه به پروژههای تحت وب MVC است. همانطور که از نام آن پیداست این کتابخانه صرفا برای پروژههای WPF طراحی شده، در نتیجه در پروژههای Silverlight نمیتوان از آن استفاده کرد.
ساختار کلی آن به شکل زیر میباشد:
معرفی برخی مفاهیم:
»Shell : این کلاس معادل یک فایل Xaml است که حتما باید یک اینترفیس IView را پیاده سازی نماید.
»IView : معرف یک اینترفیس جهت برقراری ارتباط بین ViewModel و Shell
»ViewModel : در این جا ViewModel با مفهوم ViewModel در سایر کتابخانههای MVVM کمی متفاوت است. در این کتابخانه ViewModel فقط شامل تعاریف است و هیچ گونه پیاده سازی در اینجا صورت نمیگیرد. دقیقا معادل مفهوم ViewModel در پروژههای MVC تحت وب.
»Controller : پیاده سازی ViewModel و تعریف رفتارها در این قسمت انجام میگیرد.
اما در بسیاری از پروژها نیاز به پیاده سازی الگوی DataModel-View-ViewModel است که این کتابخانه با دراختیار داشتن برخی کلاسهای پایه این مهم را برایمان میسر کرده است.
سرویسهای پیش فرض: که شامل DialogBox جهت نمایش پیغامها و Save|Open File Dialog سفارشی نیز میباشد.
»برای پیاده سازی Modularity از کتابخانه MEF استفاده شده است.
Commandهای سفارشی: پیاده سازی خاص از اینترفیس ICommand
»مفاهیم مربوط به Weak Event Pattern به صورت توکار در این کتابخانه تعبیه شده است.
»به صورت پیش فرض مباحث مربوط به اعتبارسنجی با استفاده از DataAnnotation و IDataErrorInfo در این کتابخانه تعبیه شده است.
»ارائه Extensionهای مربوط به UnitTest نظیر Exceptions و CanExecuteChangedEvent و PopertyChanged جهت سهولت در تهیه unit test
دانلود و نصب
با استفاده از nuget و دستور زیر میتوانید این کتابخانه را نصب نمایید:
هم چنین میتوانید سورس آن به همراه فایلهای باینری را از اینجا دریافت کنید. در پست بعدی یک نمونه از پیاده سازی مثال با این کتابخانه را بررسی خواهیم کرد.
اما نکته ای که ذکر آن خالی از لطف نیست این است که قبلا از این کتابخانه در یک پروژه بزرگ و ماژولار WPF استفاده کردم و نتیجه مطلوب نیز حاصل شد.
معرفی:
WPF Application Framework یا به اختصار WAF کتابخانه کم حجم سبک و البته با کارایی عالی برای طراحی پروژههای ماژولار WPF در مقیاس بزرگ طراحی شده است که مدل پیاده سازی ان بر مبنای مدل MVVM و MVC است. شاید برایتان جالب باشد که این کتابخانه دقیقا مدل MVC را با مدل MVVM ترکیب کرده در نتیجه مفاهیم آن بسیار شبیه به پروژههای تحت وب MVC است. همانطور که از نام آن پیداست این کتابخانه صرفا برای پروژههای WPF طراحی شده، در نتیجه در پروژههای Silverlight نمیتوان از آن استفاده کرد.
ساختار کلی آن به شکل زیر میباشد:
همانطور که مشاهده میکنید پروژههای مبتنی بر این کتابخانه همانند سایر کتابخانههای MVVM از سه بخش تشکیل شده اند. بخش اول با عنوان Shell یا Presentation معرف فایلهای Xaml پروژه است، بخش دوم یا Application معرف ViewModel و Controller و البته IView میباشد. بخش Domain نیز در برگیرنده مدلهای برنامه است.
معرفی برخی مفاهیم:
»Shell : این کلاس معادل یک فایل Xaml است که حتما باید یک اینترفیس IView را پیاده سازی نماید.
»IView : معرف یک اینترفیس جهت برقراری ارتباط بین ViewModel و Shell
»ViewModel : در این جا ViewModel با مفهوم ViewModel در سایر کتابخانههای MVVM کمی متفاوت است. در این کتابخانه ViewModel فقط شامل تعاریف است و هیچ گونه پیاده سازی در اینجا صورت نمیگیرد. دقیقا معادل مفهوم ViewModel در پروژههای MVC تحت وب.
»Controller : پیاده سازی ViewModel و تعریف رفتارها در این قسمت انجام میگیرد.
اما در بسیاری از پروژها نیاز به پیاده سازی الگوی DataModel-View-ViewModel است که این کتابخانه با دراختیار داشتن برخی کلاسهای پایه این مهم را برایمان میسر کرده است.
همانطور که میبینید در این حالت بر خلاف حالت قبلی ViewModel و کنترلرهای پروژه به جای ارتباط با مدل با مفهوم DataModel تغذیه میشوند که یک پیاده سازی سفارشی از مدلهای پروژه است. هم چنین این کتابخانه یک سری Converterهای سفارشی جهت تبدیل Model به DataModel و برعکس را ارائه میدهد.
سرویسهای پیش فرض: که شامل DialogBox جهت نمایش پیغامها و Save|Open File Dialog سفارشی نیز میباشد.
»برای پیاده سازی Modularity از کتابخانه MEF استفاده شده است.
Commandهای سفارشی: پیاده سازی خاص از اینترفیس ICommand
»مفاهیم مربوط به Weak Event Pattern به صورت توکار در این کتابخانه تعبیه شده است.
»به صورت پیش فرض مباحث مربوط به اعتبارسنجی با استفاده از DataAnnotation و IDataErrorInfo در این کتابخانه تعبیه شده است.
»ارائه Extensionهای مربوط به UnitTest نظیر Exceptions و CanExecuteChangedEvent و PopertyChanged جهت سهولت در تهیه unit test
دانلود و نصب
با استفاده از nuget و دستور زیر میتوانید این کتابخانه را نصب نمایید:
Install-Package waf
نظرات مطالب
معرفی پروژه Orchard
مستندات orchard را از وب سایتش خواندم . برای مطالعه سورس آن هم وقت گذاشتم. گیج کننده است . نقطه آغاز و نقشه راه آن برایم روشن نشده است . نتوانستم بفهمم در زمان اجرا چه اتفاقی میافتد . dashboard آن چگونه فراخوانی میشود و چگونه میتوان رابط کاربری dashboard را مطابق میل خود طراحی مجدد کرد. در این زمینه میتوانید مرا کمک کنید و یا منابعی را که راجع به سورس کد آن توزیع میدهد معرفی کنید ؟
همانطور که در نکته انتهای قسمت قبل «کار با بانکهای اطلاعاتی مختلف در PdfReport» عنوان شد، ذکر قسمت MainTableColumns و تمام تعاریف مرتبط با آن در PdfReports اختیاری است. برای تهیه یک گزارش توسط PdfReport فقط کافی است تا منبع داده را جهت تولید ستونهای گزارش مشخص کنید.
این مورد انعطاف پذیری زیادی را به همراه خواهد داشت؛ اما ... پس از مدتی این سؤالات مطرح میشوند: آیا میشود در این ستونهای خودکار، فیلدهای DateTime، با تاریخ شمسی نمایش داده شوند؟ آیا امکانپذیر است که ستونهای عددی، جمع پایین صفحه داشته باشند؟ و مواردی از این دست که در مورد نحوه مدیریت این نوع ستونهای خودکار در ادامه بحث خواهد شد.
ابتدا سورس کامل مثال جاری را در ادامه ملاحظه خواهید کرد. تقریبا همان مثال قسمت قبل است که تعاریف ستونهای آن حذف شده است:
توضیحات:
- با توجه به اینکه تعاریف ستونها را حذف کردهایم و به این ترتیب ستونها به صورت خودکار بر اساس فیلدهای معرفی شده در منبع داده تشکیل میشوند، نیاز است سر ستونها را بتوانیم فارسی نمایش دهیم. به همین جهت اینبار کوئری SQL ما با استفاده از aliasها، نامی فارسی را جهت فیلدها تدارک دیده است:
- در مرحله بعد توسط متد MainTableAdHocColumnsConventions، یک سری روال را جهت پردازش و نمایش این ستونهای پویا مشخص میکنیم. برای مثال علاقمندیم در این نوع گزارشات هم ستون خودکار ردیف ظاهر شود:
همچنین هر ستونی که نوع دادهاش DateTime بود، از طریق فرمولی که مشخص میکنیم، به صورت شمسی نمایش داده شود:
به علاوه میخواهیم تمام ستونهایی از نوع Int64، دارای جمع پایین صفحه هم باشند:
نوع int در بانک اطلاعاتی SQLite معادل نوع Int64 در دات نت است.
این مورد انعطاف پذیری زیادی را به همراه خواهد داشت؛ اما ... پس از مدتی این سؤالات مطرح میشوند: آیا میشود در این ستونهای خودکار، فیلدهای DateTime، با تاریخ شمسی نمایش داده شوند؟ آیا امکانپذیر است که ستونهای عددی، جمع پایین صفحه داشته باشند؟ و مواردی از این دست که در مورد نحوه مدیریت این نوع ستونهای خودکار در ادامه بحث خواهد شد.
ابتدا سورس کامل مثال جاری را در ادامه ملاحظه خواهید کرد. تقریبا همان مثال قسمت قبل است که تعاریف ستونهای آن حذف شده است:
using System; using PdfRpt; using PdfRpt.Core.Contracts; using PdfRpt.Core.Helper; using PdfRpt.FluentInterface; namespace PdfReportSamples.AdHocColumns { public class AdHocColumnsPdfReport { public IPdfReportData CreatePdfReport() { return new PdfReport().DocumentPreferences(doc => { doc.RunDirection(PdfRunDirection.RightToLeft); doc.Orientation(PageOrientation.Portrait); doc.PageSize(PdfPageSize.A4); doc.DocumentMetadata(new DocumentMetadata { Author = "Vahid", Application = "PdfRpt", Keywords = "Test", Subject = "Test Rpt", Title = "Test" }); }) .DefaultFonts(fonts => { fonts.Path(AppPath.ApplicationPath + "\\fonts\\irsans.ttf", Environment.GetEnvironmentVariable("SystemRoot") + "\\fonts\\verdana.ttf"); }) .PagesFooter(footer => { footer.DefaultFooter(printDate: DateTime.Now.ToString("MM/dd/yyyy")); }) .PagesHeader(header => { header.DefaultHeader(defaultHeader => { defaultHeader.ImagePath(AppPath.ApplicationPath + "\\Images\\01.png"); defaultHeader.Message("گزارش جدید ما"); }); }) .MainTableTemplate(template => { template.BasicTemplate(BasicTemplate.SilverTemplate); }) .MainTablePreferences(table => { table.ColumnsWidthsType(TableColumnWidthType.Relative); }) .MainTableDataSource(dataSource => { dataSource.GenericDataReader( providerName: "System.Data.SQLite", connectionString: "Data Source=" + AppPath.ApplicationPath + "\\data\\blogs.sqlite", sql: @"SELECT [url] as 'آدرس', [name] as 'نام', [NumberOfPosts] as 'تعداد مطالب', [AddDate] as 'تاریخ ارسال' FROM [tblBlogs] WHERE [NumberOfPosts]>=@p1", parametersValues: new object[] { 10 } ); }) .MainTableSummarySettings(summary => { summary.OverallSummarySettings("جمع کل"); summary.PreviousPageSummarySettings("نقل از صفحه قبل"); summary.PageSummarySettings("جمع صفحه"); }) .MainTableAdHocColumnsConventions(adHocColumns => { //We want sum of the int columns adHocColumns.AddTypeAggregateFunction( typeof(Int64), new AggregateProvider(AggregateFunction.Sum) { DisplayFormatFormula = obj => obj == null ? string.Empty : string.Format("{0:n0}", obj) }); //We want to dispaly all of the dateTimes as ShamsiDateTime adHocColumns.AddTypeDisplayFormatFormula( typeof(DateTime), data => { return PersianDate.ToPersianDateTime((DateTime)data); } ); adHocColumns.ShowRowNumberColumn(true); adHocColumns.RowNumberColumnCaption("ردیف"); }) .MainTableEvents(events => { events.DataSourceIsEmpty(message: "There is no data available to display."); }) .Export(export => { export.ToExcel(); export.ToXml(); }) .Generate(data => data.AsPdfFile(AppPath.ApplicationPath + "\\Pdf\\AdHocColumnsSampleRpt.pdf")); } } }
توضیحات:
- با توجه به اینکه تعاریف ستونها را حذف کردهایم و به این ترتیب ستونها به صورت خودکار بر اساس فیلدهای معرفی شده در منبع داده تشکیل میشوند، نیاز است سر ستونها را بتوانیم فارسی نمایش دهیم. به همین جهت اینبار کوئری SQL ما با استفاده از aliasها، نامی فارسی را جهت فیلدها تدارک دیده است:
SELECT [url] as 'آدرس', [name] as 'نام', [NumberOfPosts] as 'تعداد مطالب', [AddDate] as 'تاریخ ارسال' FROM [tblBlogs] WHERE [NumberOfPosts]>=@p1
adHocColumns.ShowRowNumberColumn(true); adHocColumns.RowNumberColumnCaption("ردیف");
adHocColumns.AddTypeDisplayFormatFormula( typeof(DateTime), data => { return PersianDate.ToPersianDateTime((DateTime)data); } );
adHocColumns.AddTypeAggregateFunction( typeof(Int64), new AggregateProvider(AggregateFunction.Sum) { DisplayFormatFormula = obj => obj == null ? string.Empty : string.Format("{0:n0}", obj) });
نظرات مطالب
جلوگیری از ارسال Spam در ASP.NET MVC
خطا !
سورس فایل jquery.unobtrusive-ajax.js به همراه پروژههای MVC موجود است. میتوانید موارد مدنظر رو در اون بررسی کنید، مثلا نحوه انتقال اطلاعات یا نحوه گوش فرا دادن به دکمه submit در آن. سورس باز هم هست. تغییرش بدید، بعد نتایج رو برای حذف کدهای تکراری کپسوله کنید (اصل بحث جاری).
نظرات مطالب
Senior Developer به چه کسی گفته می شود؟
یک کار بهتر بجای این سؤال و جوابها یا مشاهده رزومه میتونه مراجعه به پروژههای سورس باز یک شخص باشه و بررسی کیفیت کدهای نوشته شده او. اصلا یکی از اهداف کارهای سورس باز نمایش توانمندیهای فنی افراد است.
بله. مرورگرهایی که XMLHttpRequest Level 2 را پشتیبانی کنند (از IE 10 به بعد مثلا)، امکان Ajax upload توکار به همراه گزارش درصد آپلود را بدون نیاز به فلش یا سیلورلایت، دارند.یک نمونه پیاده سازی آن