نظرات مطالب
ساخت ربات تلگرامی با #C
با تشکر از این مطلب مفید. بنده هم چند روز پیش سری به مستندات تلگرام زدم و یه ربات با تمام قابلیت هاش طراحی کردم. در این مورد نکات کلی هست که انشاله مورد استفاده قرار بگیره.
برای ایجاد ربات بهتره با کتابخانه پیشنهادی خود تلگرام کار کنید.(اینجا ) و یا اون رو از طریق Nuget دریافت کنید.
pm> Install-Package Telegram.Bot
درمورد دو روش کار با ربات باید بدونید که روش getUpdate فقط برای تست کردن پاسخگویی ربات بهتره استفاده بشه و اگراصرار به استفاده از این حالت دارید ربات شما نمیتونه به چندین کاربر پاسخ بده چون طبق این روش در هر لحظه برای  مثال 10 آپدیت دریافت میشه این آپدیت‌ها همون درخواست‌های کاربرا هستن پس درخواست یازدهم باید صبر کنه تا 10 درخواست اول پاسخ داده بشن. حل شد؟
روش اصلی که شما برای ربات باید استفاده کنید همون Webhook هست اما این هم نکاتی داره. طبق قواعد تلگرام برای استفاده از این روش باید حتما ssl روی دامنه شما فعال باشه و شما هم باید یه وب سرویس برای پاسخگویی به درخواست‌ها پیاده کنید.
برای دریافت ssl رایگان میتونید از CloudFlare استفاده کنید که اگر بگردید آموزش هاش هست و کار راحتیه
برای پیاده سازی وب سرویس اون هم با Web Api  میتونید از این مثال استفاده کنید.
حالا بعد از اینکه ربات رو توی حالت getupdate طراحی و تست کردید میتونید اون رو به حالت webhook منتقل کنید.
نکته ای هم که وجود داره اینه که شما نمیتونید به طور همزمان برای یک ربات هم از webhook و هم از getupdate استفاده کنید !
پس برای زمانی که ربات رو در حالت webhook منتشر کردید ولی دوباره نیاز به تست و دیباگ دارید و میخواید از getupdate استفاده کنید باید حتما حالت webhook  رو با استفاده از فراخوانی api زیر غیر فعال کنید (داخل آدرس بار مرورگر).
https://api.telegram.org/bot[bot-token]/setwebhook
به جای [bot-token]  باید توکن ربات خودتون رو بذارید.
بعد دوباره برای فعال کردن webhook میتونید فراخوانی زیر رو داشته باشید.
https://api.telegram.org/bot[bot-token]/setwebhook?url=https://yourdomain.example/api/webhook  
نظرات مطالب
نقدی بر کتاب «مرجع کامل entity framework 4.1»
باسلام.
با تشکر از جناب راد بابت کتاب خوبشون.
این کتاب بسیار عالی است فقط چند مورد زیر جهت بهبود و تکمیل کتاب پیشنهاد می‌گردد:

1- خیلی مقدمه چینی داره و از نظر بنده حقیر نیاز نبوده و صرفا مستقیم اگر می‌رفتند سر اصل مطلب و نحوه استفاده در پروژه رو بصورت تصویری و عملی می‌گفتند خیلی بهتر بود.
ابتدای کتاب و مقدمه چینی‌های زیاد آن آدم و خسته می‌کنه.

2- مثال در زمینه کد نویسی lambda و  linq خیلی کم است و جای خالی چند مثال عملی (پروژه واقعی) خوب به شدت حس می‌شود.
به شخصه دوست داشتم چند مثال خیلی خوب عملی از روش first Database و first code ببینم که متاسفانه وجود نداشت.

البته این نظر بنده است و بنده در سطحی نیستم که درباره کتاب جناب راد فکر کنم (چه برسه به نظر دادن) و خودم رو در چنین سطحی نمی‌بینم.
صرفا در جهت پیشنهاد و در جهت کمک به بهتر شدن کتاب عرض کردم.
تقریبا بیشتر کتاب‌های جناب راد را دارم و به شخصه E.F رو از روی همین کتاب یاد گرفتم و این کتاب مرجع آموزش E.F برخی از اساتید مجتمع فنی تهران نیز می‌باشد که همانا نشان از سطح بسیار خوب این کتاب دارد.
مشتاقانه در انتظار انتشار کتاب‌های دیگری از جناب راد در زمینه هایی همچون "برنامه نویسی پروژه‌های بزرگ بصورت چند لایه" و یا Nuget (بهترین پلاگین‌های آن) می‌باشم.
(جای خالی همچین کتابهایی واقعا خالیه)

*در تایید حرف‌های جناب نصیری هم باید عرض کنم که بنده شخصا چنین کتابی اگر به پستم بخوره حتما یکیشو می‌خرم و جالب اینه که بنده کتاب E.F رو که می‌خواستم بخرم ، توی بازار هیچی نبود!
به انتشارات که مراجعه کردم دقیقا آخرین کتاب به بنده رسید :دی
(البته داستانش طولانیه که چطوری یک کتاب رو برای بنده نگهداشته بودند و تونستم آخرین نسخه موجود رو بخرم :دی )
خدا قوت
یا حق
نظرات مطالب
EF Code First #4
از توجهتون سپاسگزارم.
مهندس جان من اینکار را انجام دادم و پاورشل را هم ارتقاء دادم، ولی مشکل برطرف نشد.
یه پروژۀ جدید ایجاد کردم و همۀ فایل‌های کد پروژۀ قبلی (بغیر از app.config) را بهش اضافه کردم و بعد با استفاده از NuGet نسخۀ آخر EF را به پروژه اضافه کردم. کانکشن استرینگ را به پروژه اضافه نکردم (کلاً به app.config دست نزدم) و دستور enable-migrations را اجرا کردم. دستور با موفقیت اجرا شد و اون چیزهایی که فرمودین به پروژه اضافه شد.
دیتابیس را به صورت دستی Drop کردم و یه بار برنامه را اجرا کردم و بعد از اون هم تغییراتی که به مدل دادم به دیتابیس اعمال شد و رکوردهای مربوط بهش داخل جدول dbo.__MigrationHistoryثبت شد.

رفتم به درس پنجم، و دوباره به محض بازکردن کنسول همون پیغامی را که توی کامنت اولم نوشتم می‌نویسه و وقتی هم می‌خوام که دستور Add-Migration را اجرا کنم، همون چیزی را می‌نویسه که قبلاً برای enable-migrations می‌نوشت. جالب اینکه برای خود دستور enable-migrations هم همینو می‌نویسه!برای دستور Update-Database هم همینطور، در حالی که برای پروژۀ شما می‌نوشت که هم اکنون فعال هست.

فکرمی‌کنم مشکل از فایل ‪init.psd1 باشه که هنگام اضافه کردن EF در فولدر tools ایجاد میشه.
من فایل init.psd1 را که در پوشۀ tools مربوط به پروژۀ ایجاد شده توسط شما قرار داشت جایگزین فایل با همین نام که در پروژۀ خودم بود کردم و مشکل برطرف شد. نمی‌دونم ایراد کار چیه؟ من قدم به قدم همونطور که شما نوشتین پیش رفته‌م و چیزی را هم تغییر نداده‌م. آیا ممکنه توی پروژه‌هایی که می‌خوام از EF استفاده کنم این مسئله دردسرساز بشه؟
نظرات مطالب
NuGet 2.0 منتشر شد
درهر حالتی اگه شما بخواین نسخه ای از نوگت رو به روز رسانی بکنین یکسری خطاهایی ممکنه به وجود بیاد. البته ظاهرا این مشکل نوگت نیست (^ و ^) بلکه به یه ایرادهای خاص در Visual Studio Extension manager بر میگرده (^ و ^) : Hotfix و یا این مورد:

Attempting to install or uninstall results in the error "Cannot create a file when that file already exists.”
For some reason, Visual Studio extensions can get in a weird state where you've uninstalled the VSIX extension, but some files were left behind. To work around this issue:

1. Exit Visual Studio
2. Open the following folder (it might be on a different drive on your machine)
    C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\Extensions\Microsoft Corporation\NuGet Package Manager\<version>\
3. Delete all the files with the .deleteme extensions.
4. Re-open Visual Studio
After following these steps, you should be able to continue.

مطالب
تقویم شمسی در Xamarin Forms
BitDatePicker یک Date Picker، برای استفاده در برنامه‌هایی مبتنی بر زمارین فرم (Android - iOS - UWP) است.

مهم‌ترین ویژگی ها:
  • پشتیبانی از تمامی Calendar System هایی که noda time ساپورت می‌کند؛ اعم از شمسی، قمری، میلادی و ...
  • پشتیبانی از تمامی Locale هایی که NET. پشتیبانی می‌کند؛ اعم از فارسی، عربی، انگلیسی و ...
  • قابلیت ارائه Template سفارشی شده برای UI
  • سازگار شده با MVVM
بر روی گیت هاب یک نمونه کد که در آن از کنترل BitDatePicker استفاده شده، قرار داده‌ایم. در ادامه  توضیح مختصری را از نحوه‌ی استفاده‌ی از آن داریم.

چگونه BitDatePicker را در پروژه‌ی خود داشته باشیم؟
  • دریافت و نصب پکیج Bit.CSharpClient.Controls از nuget.
  • اضافه کردن کدهای زیر در کلاس AppDelegate پروژه‌ی iOS و کلاس Main Activity در Android و کلاس App پروژه‌ی UWP قبل از Forms.Init .
BitCSharpClientControls.Init();

چگونگی استفاده از BitDatePicker در فرم Xaml: 
  • اضافه کردن namepsace های زیر در فرم Xaml:

  • xmlns:bitControls="clr-namespace:Bit.CSharpClient.Controls;assembly=Bit.CSharpClient.Controls"
    xmlns:noda="clr-namespace:NodaTime;assembly=NodaTime"

    مثال تقویم شمسی:
<bitControls:BitDatePicker
    Text="لطفا یک روز را انتخاب کنید" 
    Culture="Fa"
    DateDisplayFormat="dd MMM yyyy"
    CalendarSystem="{x:Static noda:CalendarSystem.PersianArithmetic}"
    FlowDirection="RightToLeft" 
    SelectedDate =" {Binding SelectedDate}"/>

برای داشتن تقویم شمسی  با اعداد فارسی تنها کافی است از یک Font که همیشه اعداد فارسی را در خود دارد مثل Vazir-FD-WOL، استفاده کنیم. فونتی سبک، سورس باز و زیبا! (FD مخفف Farsi Digit و WOL مخفف Without Latin است)

برای درک بهتر از نحوه‌ی استفاده‌ی از این Date Picker، نگاهی به Sample های آن بیاندازید. همچنین می‌توانید در همینجا نیز سؤالات خود را بپرسید؛ یا این که در Stackoverflow.com سوال ایجاد کنید و یا در GitHub یک Issue را ثبت کنید.

مطالب
توسعه برنامه‌های Cross Platform با Xamarin Forms & Bit Framework - قسمت هشتم
تا اینجا می‌دانیم که View که با Xaml نوشته می‌شود؛ مسئولیت ظاهر صفحات را به عهده داشته و View Model که با CSharp نوشته می‌شود نیز منطق هر صفحه را مدیریت می‌کند.
حال اگر بخواهیم در مثال Login، در صورتی که UserName و یا Password خالی بودند، به کاربر هشدار دهیم چه؟ برای این کار شما می‌توانید با توجه به دسترسی کد CSharp به صد در صد امکانات هر سیستم عامل، مثلا در Android از MakeToast استفاده کنید، ولی این کار باعث می‌شود مجبور شوید برای Android - iOS - Windows کدی متفاوت بنویسید که البته همه CSharp ای هستند، ولی به هر حال سه بار نوشتن یک چیز اصلا جالب نیست!
توجه: اگر پروژه XamApp را ندارید، آن را Clone کنید و اگر دارید، آخرین تغییرات را Pull کنید. مواردی که در ادامه گفته شده‌اند، در آخرین سورس‌های پروژه XamApp وجود دارند.
یک کتابخانه که این کار را برای ما ساده سازی می‌کند Acr User Dialogs است که قابلیت نمایش دادن Toast - Alert - Confirm - Action Sheet - Loading و ... را با یک کد و برای هر سه پلتفرم دارد. برای استفاده از این کتابخانه، ابتدا روی پروژه XamApp راست کلیک کرده و در Manage Nuget Packages پکیج Acr User Dialogs را نصب کنید.
برای نصب Package مربوطه، دقت کنید که Package Source در گوشه سمت راست-بالا روی All قرار گرفته باشد:

سپس در پروژه XamApp.Android، در کلاس Main Activity، کد زیر را قرار دهید:
 UserDialogs.Init(this); // Before Forms.Init
ممکن است ویژوال استودیو کلاس UserDialogs را نشناسد و کمکی برای افزودن using مربوطه در بالای کلاس MainActivity نکند. در این صورت ویژوال استودیو را باز و بسته کنید تا روال Restore کردن Nuget Package‌ها این بار به صورت کامل انجام شود و بتوانید این کلاس را ببینید و استفاده کنید.
نکته مهم: در آموزش خیلی از کتابخانه‌های Xamarin Forms، به شما گفته می‌شود که Nuget مربوطه را در پروژه Android-iOS-UWP نیز نصب کنید. در نسخه‌های اخیر Visual Studio نیازی به این کار نیست و بیهوده پروژه را شلوغ نکنید!

بعد از نصب، می‌توانیم از UserDialogs.Instance و متدهای آن برای نمایش هشدار و ... در هر جای پروژه استفاده کنیم؛ چون که اینها  static هستند. اما اگر اهل استفاده از Dependency injection و تست خودکار و سایر موارد ایده آل باشید، می‌دانید که استفاده از هر آنچه که static باشد، در اکثر مواقع ایده خوبی نیست.
کانفیگ کردن Dependency injection برای این کتابخانه کار ساده‌ای است. فقط کافی است کد زیر را در فایل App.xaml.cs در پروژه XamApp، به متد RegisterTypes اضافه کنید:
containerBuilder.RegisterInstance(UserDialogs.Instance);
RegisterInstance یکی از متدهای کتابخانه معروف و محبوب Autofac است که برای Dependency injection ساخته شده است.
در متد Login در LoginViewModel برای هشدار دادن خالی بودن نام کاربری یا رمز عبور، به جای استفاده مستقیم از UserDialogs.Instance می‌توانیم IUserDialogs را به صورت یک Property تعریف نموده و از آن استفاده کنیم. وظیفه پر کردن آن Property به عهده Autofac است و ما کار بیشتری نداریم!
public IUserDialogs UserDialogs { get; set; }

public async Task Login()
{
      if (string.IsNullOrWhiteSpace(UserName) || string.IsNullOrWhiteSpace(Password))
           await UserDialogs.AlertAsync(message: "Please provide UserName and Password!", title: ")-:", okText: "Ok!");
}
به سادگی نصب یک Nuget Package در پروژه XamApp، فراخوانی یک متد Init در پروژه XamApp.Android و یک خط کانفیگ برای Autofac، می‌توانید از IUserDialogs در تمامی View Model‌های خود استفاده کنید.
فرض کنید بعد از این که مطمئن شدید نام کاربری و رمز عبور خالی نیستند، می‌خواهید یک Request به سرور بفرستید و نام کاربری و رمز عبور را اعتبار سنجی کنید. ممکن است به خاطر کندی اینترنت یا سرور یا هر چیز دیگری، این پروسه کمی طول بکشد و نشان دادن یک Loading ایده خوبی است. چون فعلا نمی‌خواهیم درگیر فراخوانی سرور شویم، این طول کشیدن را من با Task.Delay شبیه سازی می‌کنم و Loading مربوطه را نمایش می‌دهم:
using (UserDialogs.Loading("Logging in...", maskType: MaskType.Black))
{
     // Login implementation ...
     await Task.Delay(TimeSpan.FromSeconds(3));
}

بررسی Navigation در Xamarin Forms
اگر در متد OnInitializedAsync در App.xaml.cs کد
await NavigationService.NavigateAsync("/Login", animated: false);
را داشته باشیم، وقتی برنامه اجرا می‌شود، ما به صفحه لاگین می‌رویم؛ این از تکلیف اولین صفحه برنامه! حال اگر در LoginViewModel بخواهیم در صورت موفقیت آمیز بودن فرآیند لاگین، مثلا به صفحه HelloWorld برویم چه؟ در این صورت در متد Login داریم:
await NavigationService.NavigateAsync("/Nav/HelloWorld");
چون کلاس LoginViewModel از BitViewModelBase ارث بری کرده است، به صورت پیش فرض دارای NavigationService هست. در رشته (string) استفاده شده، یعنی "/Nav/HelloWorld" چند نکته وجود دارد:
1- آن / اول اگر وجود داشته باشد، یعنی اینکه بعد از باز کردن صفحه HelloWorld، صفحه یا صفحات قبلی (در این مثال یعنی صفحه Login) از بین برده می‌شوند و امکان برگشت به آنها وجود ندارد. طبیعی است که بعد از لاگین موفق، فرد انتظار ندارد با زدن Back به صفحه لاگین باز گردد! ولی مثالی را فرض کنید که در یک صفحه، لیست محصولات فروشگاه را نمایش داده‌ایم و روی هر محصول که کلیک کنیم، به صفحه نمایش جزئیات آن محصول می‌رویم. در این صورت انتظار داریم با زدن Back، به صفحه لیست محصولات برگردیم، در این مثال از / در ابتدا استفاده نمی‌کنیم.

2- آن Nav/ به معنی این است که ابتدا Navigation Page را ایجاد و HelloWorld را درون Navigation Page باز کن. Navigation Page خود دارای امکانات زیادی است. عموما در برنامه‌ها، Title صفحه و دکمه Back نرم افزاری و Search bar را در Nav Bar مربوط به Navigation Page قرار می‌دهند. در Xamarin Forms حتی می‌توانید با Xaml، کل Nav Bar را خودتان Customize کنید و یا اینکه از امکان Large titles در iOS 11 استفاده کنید! درخواست بودن Nav Bar لازم است فقط یک بار انجام شود. لازم نیست و نباید ابتدای رفتن به هر صفحه از Nav/ استفاده کنید.


3- ممکن است بخواهید هنگام رفتن از صفحه‌ای به صفحه دیگر، پارامتر نیز ارسال کنید. اگر برای مثال صفحه اول لیست محصولات را نمایش می‌دهد و با زدن روی هر محصول قرار است به صفحه‌ای برویم که جزئیات آن محصول را ببینیم، بهتر است Id آن محصول به صورت پارامتر به صفحه دوم ارسال شود. برای این کار داریم:

await NavigationService.NavigateAsync("ProductDetail", new NavigationParameters
{
      { "productId", productId }
});

حال سؤال این است که در صفحه جزئیات یک محصول، چگونه productId را بگیریم؟ فرض کنید دو صفحه ProductsList و ProductDetail را داریم. هر صفحه دارای View و View Model است. در ViewModel مربوط به ProductDetail، یعنی ProductDetailViewModel که از BitViewModelBase ارث بری کرده‌است، می‌توانیم متد OnNavigatedToAsync را override کنیم. در آنجا به پارامترهای ارسال شده دسترسی داریم:

public async override Task OnNavigatedToAsync(INavigationParameters parameters)
{
      await base.OnNavigatedToAsync(parameters);
      Guid productId = parameters.GetValue<Guid>("productId");
}

هر ViewModel علاوه بر OnNavigatedTo می تواند دارای OnNavigatedFrom هم باشد که زمانیکه داریم از صفحه مربوطه خارج می‌شویم، فراخوانی می‌شود.


4- برای نمایش صفحه به صورت Popup کافی است بجای اینکه View ما یک Content Page باشد، یک PopupPage باشد (برای درک بهتر، فایل IntroView.xaml را در فولدر Views باز کنید).

حتی می‌توانید Animation مربوط به باز شدن پاپ آپ را هم کاملا Customize کنید. مثلا زمان باز شدن، از سمت راست صفحه وارد شود و زمان خارج شدن، Fade out شود. باز کردن Popup در Navigation Page معنی نمی‌دهد، پس با Nav/ در اینجا کاری نداریم. در مثال ما، بعد از لاگین می‌خواهیم یک صفحه Intro شامل هشدارها و راهنمایی‌های اولیه را در قالب Popup به کاربر نمایش دهیم. Popup‌ها می‌توانند همچون Content Page‌ها، دارای View Model باشند و مواردی چون OnNavigatedTo، ارسال پارامتر و هر آنچه که گفته شد، در مورد آنها نیز صدق می‌کند.


5- برای Master/Detail کافی است بجای Nav/HelloWorld/ از MasterDetail/Nav/HelloWorld/ استفاده کنید. این عمل باعث می‌شود HelloWorld در داخل Navigation Page و Navigation Page داخل Master Detail باز شود. از این ساده‌تر امکان ندارد!

برای تغییر UI مربوط به Master که از سمت چپ باز می‌شود، فایل XamAppMasterDetailView.xaml را تغییر دهید.


در قسمت بعدی به جزئیات Binding خواهیم پرداخت.

مطالب
ارسال پیام های تبلیغاتی به Telegram با استفاده از #C
ارسال پیام‌های تبلیغاتی از طریق نرم افزارهایی مثل Viber , Telegram  این روزها بازار داغی دارند. این نرم افزارها به همراه خود Api هایی را نیز جهت توسعه دهندگان ارائه می‌دهند. Telagram هم که به یکی از محبوب‌ترین نرم افزارها در ایران تبدیل شده‌است. اگر به مستندات Telegram مراجعه کنید، می‌توانید نحوه‌ی استفاده را مشاهده کنید. ولی روش‌های دیگری هم هستند که بسیار ساده‌تر هستند.
اگر به سایت notificatio.me مراجعه کنید، در این زمینه Api ایی را ارائه می‌دهد که به راحتی می‌توانید از آن برای ارسال پیام استفاده کنید. البته تا ارسال 100 پیام آن رایگان هست.
ابتدا یک پروژه‌ی از نوع Windows و یا console را ایجاد کنید.
سپس  در خط فرمان package manager console دستور زیر را کپی کنید:
Install-Package Notificatio.TelegramClient
پس از نصب شدن بسته‌ی Nuget، یک دکمه روی فرم قرار دهید و در رویداد OnClick آن دستورات زیر را تایپ کنید:
var api = NotificatioApi.Initialize(" Your Hash_Key");
            api.SendMessage("Phone Number", "this is a test Message");
سپس در سایت notificatio.me ثبت نام کنید و پس از ثبت نام، به پروفایلتان رفته و Api Hash ایی را که در آنجا قابل مشاهده هست، کپی و به جای Your Hash_Key قرار دهید. برای شماره تلفن هم فقط از اعداد استفاده کنید.
در آخر برنامه را اجرا کنید و بر روی دکمه، کلیک کنید. پس از اتمام کار ارسال، برای مشاهده‌ی تعداد پیام‌های ارسال شده و یا آمار ماهانه، در سایت فوق میتوانید به Dashboard آن مراجعه کنید و تعداد و آمار پیام‌های ارسالی را ببینید.

 البته با استفاده از jQuery هم میتوانید کار ارسال پیام را انجام دهید:
$.ajax({
    url: "http://www.api.notificatio.me/v1/user/message",
    type: "POST",
    dataType: "json",
    crossDomaint: true,
    data: {
        phoneNumber: "your_phone_number",
        apiHash: "your_api_hash",
        message: "your_message"
    },
    cache: false,
    success: function() {
        // Your code to handle success message sent
    },
    error: function(error) {
        // Your code to handle error
    }
});
مطالب
تنظیمات امنیتی Glimpse
در مورد glimpse پیشتر مطالبی در سایت منتشر شده است :
 آشنایی و بررسی ابزار Glimpse 
بعد از آپلود سایت ما می‌توانیم دسترسی به تنظیمات خاص glimpse را تنها به کاربران عضو محدود کنیم:
<location path="Glimpse.axd" >
    <system.web>
        <authorization>
            <allow users="Administrator" />
            <deny users="*" />
        </authorization>
    </system.web>
</location>

یا می‌توانیم آنرا غیرفعال کنیم :
<glimpse defaultRuntimePolicy="Off" xdt:Transform="SetAttributes">
</glimpse>

همچنین می‌توانیم با پیاده سازی اینترفیس IRuntimePolicy سیاست‌های مختلف نمایش تب‌های glimpse را تعیین کنیم :
using Glimpse.AspNet.Extensions;
using Glimpse.Core.Extensibility;

namespace Test
{
    public class GlimpseSecurityPolicy:IRuntimePolicy
    {
        public RuntimePolicy Execute(IRuntimePolicyContext policyContext)
        {
            // You can perform a check like the one below to control Glimpse's permissions within your application.
// More information about RuntimePolicies can be found at http://getglimpse.com/Help/Custom-Runtime-Policy
var httpContext = policyContext.GetHttpContext();
            if (!httpContext.User.IsInRole("Administrator "))
            {
                return RuntimePolicy.Off;
            }

            return RuntimePolicy.On;
        }

        public RuntimeEvent ExecuteOn
        {
            get { return RuntimeEvent.EndRequest; }
        }
    }
}

زمانیکه glimpse را از طریق Nuget نصب می‌کنید کلاس فوق به صورت اتوماتیک به پروژه اضافه می‌شود با این تفاوت که به صورت کامنت شده است تنها کاری شما باید انجام بدید کدهای فوق را از حالت کامنت خارج کنید و Role مربوطه را جایگزین کنید. 

نکته : کلاس فوق نیاز به رجیستر شدن ندارد و تشخیص آن توسط Glimpse به صورت خودکار انجام می‌شود.  
مطالب
ایجاد ServiceLocator با استفاده از Ninject
در پست قبلی روش استفاده از ServiceLocator رو با استفاده از Microsoft Unity بررسی کردیم. در این پست قصد دارم همون مثال رو با استفاده از Ninject پیاده سازی کنم. Ninject ابزاری برای پیاده سازی Dependency Injection در پروژه‌های دات نت است که کار کردن با اون واقعا راحته. برای شروع کلاس‌های Book و BookRepository  و BookService و اینترفیس IBookRepository از این پست دریافت کنید.
حالا با استفاده از NuGet باید ServiceLocator رو برای Ninject دریافت کنید. برای این کار در Package Manager Console دستور زیر رو وارد کنید.
PM> Install-Package CommonServiceLocator.NinjectAdapter
بعد از دانلود و نصب Referenceهای زیر به پروژه اضافه می‌شوند.
  • Ninject
  • NinjectAdapter
  • Microsoft.Practices.ServiceLocation 

اگر دقت کنید برای ایجاد ServiceLocator دارم از ServiceLocator؛Enterprise Library استفاده می‌کنم. ولی برای این کار به جای استفاده UnityServiceLocator باید از NinjectServiceLocator استفاده کنم. 

ابتدا

برای پیاده سازی مثال قبل در کلاس Program  کد‌های زیر رو وارد کنید.

using System;
using Ninject;
using NinjectAdapter;
using Microsoft.Practices.ServiceLocation;

namespace ServiceLocatorPattern
{
    class Program
    {
        static void Main( string[] args )
        {
            IKernel kernel = new StandardKernel();

            kernel.Bind<IBookRepository>().To<BookRepository>();

            ServiceLocator.SetLocatorProvider( () => new NinjectServiceLocator( kernel ) );

            BookService service = new BookService();

            service.PrintAllBooks();

            Console.ReadLine();
        }
    }
}
همان طور که می‌بینید روال انجام کار دقیقا مثل قبل هست فقط Syntax کمی متفاوت شده. برای مثال به جای استفاده از IUnityContainer از IKernel استفاده کردم و به جای دستور RegisterType از دستور Bind استفاده شده. دز نهایت هم ServiceLocator به یک NinjectServiceLocator ای که IKernel  رو دریافت کرده ست شد.
به تصویر زیر دقت کنید.

همان طور که می‌بینید در هر جای پروژه که نیاز به یک Instance از یک کلاس داشته باشید می‌تونید با استفاده از ServiceLocator این کار خیلی راحت انجام بدید.

بعد از اجرای پروژه  خروجی دقیقا مانند مثال قبل خواهد بود.

 
مطالب
قراردادن کلاس های Metdata در اسمبلی جداگانه برای کار با WCF Ria Service توسط FluentMetadata
اصلی‌ترین مزیت این پکیج ،امکان جداکردن dataModel و Metadata در پروژه یا اسمبلی جداگانه است . در حالیکه WCF RIA Service استاندارد فاقد این قابلیت میباشد و باید dataModel و Metadata در یک پروژه و در یک namespace تعریف شوند. 
برای استفاده از FluentMetadata :
1) ابتدا فرض می‌کنیم که کلاس Product ما در یک اسمبلی دیگر به نام DataModel تعریف شده است ، بصورت زیر :
public class Product
{
        public int ProductId { get; set; }
        public string ProductName { get; set; }
        public long ProductPrice { get; set; }
}
2) حال یک پروژه جدید به نام DataModelsMetadata تعریف می‌کنیم و ارجاعی به اسمبلی بالا یعنی DataModel نیز به آن اضافه می‌کنیم .
2-1) ابتدا باید پکیج FluentMetadata را توسط Nuget نصب کرد. راهنمای نصب
2-2) سپس کلاس‌های Metadata موردنظر خود را برای کلاس Product تعریف میکنیم .
public class ProductMetadata : MetadataClass<Product>
{
    public ProductMetadata ()
    {
        this.Validation(x => x.ProductName).Required("عنوان محصول وارد نشده است");
        this.Validation(x => x.ProductPrice).Range(1000,100000,"قیمت محصول باید بین هزار تومان تا صدهزار تومان باشد");
    }
}
2-3) سپس یک کلاس MetadataConfiguration که برای نمونه سازی تمام کلاس‌های متادیتا ایجاد می‌کنیم.
public class FluentMetadataConfiguration : IFluentMetadataConfiguration
{
    public void OnTypeCreation(MetadataContainer metadataContainer)
    {
        metadataContainer.Add(new ProductMetadata());
    }
}
2-4) در آخر اضافه کردن MetadataConfiguration  ایجاد شده به Domain Service توسط ویژگی FluentMetadata.
[EnableClientAccess()]
[FluentMetadata(typeof(FluentMetadataConfiguration))]
public class FluentMetadataTestDomainService : DomainService
{
    ...
}
منابع :