مطالب
استفاده از #F در پروژه های MVC4
در این پست با روش پیاده سازی پروژه‌های WPF با استفاده از #F آشنا شدید. قصد دارم در طی چند پست روش پیاده سازی پروژه‌های Asp.Net MVC 4  با استفاده از #F را شرح دهم.
»اگر با #F آشنایی ندارید می‌توانید از اینجا شروع کنید.
به صورت کلی برای استفاده گسترده از #F در پروژه‌های وب نیاز به یک سری template‌های آماده داریم در غیر این صورت کار کمی سخت خواهد شد. به تصویر زیر دقت نمایید:

واضح است که با توجه به تصویر بالا کنترلر‌ها و البته مدل‌های app  و هر آنچه که سمت سرور به آن نیاز است باید با استفاده از #F پیاده سازی شوند. اما هنگامی که کنترلر‌ها با استفاده از #F نوشته شوند سیستم مسیر یابی نیز تحت تاثیر قرار خواهد گرفت. علاوه بر آن باید فکری برای بخش Bundling و همچنین فیلتر‌هاو... نمود. در نتیجه با توجه به template پروژه مورد نظر بر خلاف حالت پیش فرض #C آن که در قالب یک پروژه ارائه می‌شود در این جا حداقل به دو پروژه نیاز داریم. خوشبختانه همانند پروژه FSharpX که برای WPF مناسب است برای MVC نیز template آماده موجود است که در ادامه با آن آشنا خواهیم شد.

شروع به کار

ابتدا در VS.Net یک پروژه جدید ایجاد نمایید. از بخش Online Template گزینه FSharp MVC 4 را جستجو کنید. 

بعد از انتخاب نام پروژه و  کلیک بر روی Ok ( و البته دانلود حدود ده MB اطلاعات) صفحه زیر نمایان می‌شود. در این قسمت تنظیمات مربوط به انتخاب View Engine و نوع قالب پروژه را وجود دارد. در صورتی که قصد استفاده از Web Api را دارید گزینه  Web Api Project را انتخاب کنید در غیر این صورت گزینه Empty Project.

البته از Visual Studio 2012 به بعد این بخش به صورت زیر خواهد بود که قسمت Single Page App به آن اضافه شده است:

بعد از کلیک بر روی Ok یک پروژه بر اساس Template مورد نظر ساخته می‌شود. همانند تصویر زیر:

بررسی تغییرات

در یک نگاه به راحتی می‌توان تغییرات زیر را در پروژه Web تشخیص داد:

»پوشه Controller وجود ندارد؛

»پوشه مدل وجود ندارد؛

»فایل Global.asax دیگر فایلی به نام Global.asax.cs را همراه با خود ندارد.

دلیل اصلی عدم وجود موارد بالا این است که تمام این موارد باید به صورت #F پیاده سازی شوند در نتیجه به پروژه #F ساخته شده منتقل شده اند. فایل Global.asax را باز نمایید. سورس زیر قابل مشاهده است:

<%@ Application Inherits="FsWeb.Global" Language="C#" %> <script Language="C#" RunAt="server">
 // Defines the Application_Start method and calls Start in // System.Web.HttpApplication from which Global inherits. protected void Application_Start(Object sender, EventArgs e) { base.Start(); } </script>
تمامی کاری که تکه کد بالا انجام می‌دهد فراخواهی متد Start در فایل Global متناظر در پروژه #F است. اگر به قسمت reference‌های پروژه Web دقت کنید خواهید که به پروژه #F متناظر رفرنس دارد.
حال به بررسی پروژه #F  ساخته شده خواهیم پرداخت. در این پروژه یک فایل  Global.fs وجود دارد که سورس آن به صورت زیر است:

namespace FsWeb

open System
open System.Web
open System.Web.Mvc
open System.Web.Routing

type Route = { controller : string
               action : string
               id : UrlParameter }

type Global() =
    inherit System.Web.HttpApplication() 

    static member RegisterRoutes(routes:RouteCollection) =
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}")
        routes.MapRoute("Default", 
                        "{controller}/{action}/{id}", 
                        { controller = "Home"; action = "Index"
                          id = UrlParameter.Optional } )

    member this.Start() =
        AreaRegistration.RegisterAllAreas()
        Global.RegisterRoutes(RouteTable.Routes)
  در پروژه‌های MVC بر اساس زبان #C،  کلاسی به نام RouteConfig وجود دارد که در فایل Global.asax.cs فراخوانی می‌شود:
RouteConfig.RegisterRoutes(RouteTable.Routes);
و کد‌های مورد نظر جهت تعیین الگوی مسیر یابی کنترلر‌ها و درخواست‌ها در کلاس RouteConfig نیز به صورت زیر می‌باشد:
public class RouteConfig
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
            );
        }
    }
اما در اینجا بر خلاف #C، تعریف و اجرای سیستم مسیر یابی در یک فایل انجام می‌شود. در بخش اول ابتدا یک type تعریف می‌شود که معادل با تعیین Routing در زبان #C است. علاوه بر آن متد RegisterRoutes جهت تعیین و انتساب Route Type تعریف شده به Route Collection مورد نظر نیز در این فایل می‌باشد. 

//تعریف الکوی مسیر یابی
type Route = { controller : string
               action : string
               id : UrlParameter }

type Global() =
    inherit System.Web.HttpApplication() 

    static member RegisterRoutes(routes:RouteCollection) =
       //فراخوانی  و انتساب الگوی مسیر یابی به  مسیر‌های تعریف شده
       routes.IgnoreRoute("{resource}.axd/{*pathInfo}")
        routes.MapRoute("Default", 
                        "{controller}/{action}/{id}", 
                        { controller = "Home"; action = "Index"
                          id = UrlParameter.Optional } )
در نهایت نیز تابع RegisterRoute در تابع Start فراخوانی خواهد شد.
Global.RegisterRoutes(RouteTable.Routes)
نتیجه کلی تا اینجا:
در این پست با Template پروژه‌های F# MVC 4 اشنا شدیم و از طرفی مشخص شد که برای پیاده سازی این گونه پروژه‌ها حداقل نیاز به دو پروژه داریم. یک پروژه که از نوع #C است ولی در آن فقط View ‌ها و فایل جاوااسکریپتی و البته Css وجود دارد. از طرف دیگر کنترلر‌ها و مدل‌ها و هر چیز دیگر که مربوط به سمت سرور است در قالب یک پروژه #F پیاده سازی می‌شود.
در پست بعدی با روش تعریف و توسعه کنترلر‌ها و مدل‌ها آشنا خواهیم شد.
مطالب
آغاز کار با WPF
من خودم به شخصه هنوز تا به حال با WPF کار نکرده‌ام؛ اما قصد دارم از امروز در هر فرصتی که پیش می‌آید به یادگیری این فناوری پر سر و صدا بپردازم. از آنجا که مجموعه‌ی مرتب و به ترتیبی مثل MVC و EF در این زمینه در سایت موجود نبود، تصمیم گرفتم که خودم استارت این کار را بزنم که باعث میشه هم خودم بهتر یاد بگیرم و هم این سری برای افراد تازه کار موجود باشه.

آشنایی اولیه
WPF مخفف عبارات Windows Presentation Foundation است که ویکی پدیا این گونه ترجمه می‌کند : بنیاد نمایش ویندوزی. در برنامه نویسی «ویندوز فرم» ما تمرکز دقیقی بر ساخت رابط کاربری برنامه به خصوص در رزولوشن‌های مختلف نداریم و در بسیاری از اوقات کد با رابط کاربری به شدت وابسته میشد که با ارائه WPF از نسخه‌ی سوم دات نت فریم ورک به بعد، این مشکل حل شد و همچنین عملیات refactoring  را بسیار ساده‌تر کرد. در حالت ویندوز فرم به خاطر وابستگی شدید کد و UI، عملیات بهینه سازی کد اصلا موفق نبود.
 WPF از ترکیب عناصر دو بعدی و سه بعدی، اسناد، موارد چند رسانه‌ای و رابط کاربری تشکیل شده‌است و موتور رندر آن بر اساس اطلاعات برداری از کارت گرافیک جهت نمایش ظاهر برنامه کمک می‌گیرد که باعث تهیه برنامه‌ای با رابط کاربری سریعتر، مقیاس پذیرتر و بدون وابستگی به رزولوشن می‌شود.

جداسازی رفتارها و ظاهر برنامه

همانطور که گفتیم بخش رابط کاربری دیگر مستقل از کد برنامه شده است و ظاهر برنامه توسط زبان نشانه گذاری XAML ایجاد می‌شود و بخش کد هم با یکی از زبان‌های موجود در مجموعه دات نت نوشته خواهد شد. نهایتا این دو بخش توسط رویدادها، فرامین و DataBinding با یکدیگر متصل می‌شوند. از مزایای جدا بودن این ویژگی:

  • عدم وابستگی این دو بخش
  • طراح و کدنویس می‌توانند هر کدام به طور جداگانه کار کنند.
  • ابزارهای طراحی میتوانند به طور جداگانه‌ای بر روی اسناد XML کار کنند بدون اینکه نیاز به درگیری با کدنویسی داشته باشند.
یکی از برنامه هایی که به طراحی رابط کاربری با پشتیبانی از XAML می‌پردازد برنامه Microsoft Experssion Blend از مجموعه Blend است


Rich Composition
یکی از ویژگی‌های XAML، ساخت اشیاء ترکیبی هست که به راحتی با ترکیب تگ‌ها با یکدیگر و قرار دادن هر شیء داخل یک شیء دیگر می‌توان به یک شیء جدید دست یافت؛ مثل قرار دادن مجموعه ویدیوها در یک لیست. شیء زیر از ترکیب سه شیء تصویر و متن و دکمه ایجاد شده است:
<Button Margin="148,123,126,130">
            <StackPanel Orientation="Horizontal">
                <Image Source="speaker.png" Stretch="Uniform"/>
                <TextBlock Text="Play Sound" VerticalAlignment="Center" Margin="10" />
            </StackPanel>
        </Button>


Highly Customizable
با استفاده از مفهوم Style همانند آنچه که در Html و CSS دارید می‌توانید اشیاء خود را خصوصی سازی کنید و ظاهر آن شیء را به طور کل تغییر دهید.



Resolution Independence
عدم وابستگی به رزولوشن یا وضوح تصویر دارد و به جای واحد پیکسل، از یک واحد منطقی که یک نود و ششم اینچ است، بهره می‌برد. از آنجا که این سیستم بر اساس وکتور ایجاد شده است، مقیاس پذیری آن در تغییر اندازه یا وضوح تصویر به شدت بالا رفته است.

به زودی در قسمت اول این سری کار را با XAML آغاز خواهیم کرد.
مطالب
مروری بر Open Data Protocol و کاربردهای آن
مقدمه
OData قراردادی برای دسترسی به داده‌ها است که مایکروسافت آن را تحت مجوز Microsoft Open Specification Promise منتشر کرده است. این قرارداد استاندارد CRUD ایی را برای دسترسی به منبع داده از طریق وب سایت طراحی نموده است که از JDBC و ODBC ساده‌تر بوده و محدودیت ارتباط فقط با پایگاه داده‌های SQL ایی را ندارد.
OData از روی Atom Publishing Protocol و JSON ساخته شده و از مدل REST برای همه در خواست‌های خود استفاده می‌نماید. OData در واقع یک راه مشترک برای هر نوع کلاینت برای دسترسی به هر نوع داده ای است.

OData چهار قسمت اصلی دارد:

  1. OData data model که یک راه عمومی برای مدیریت و توصیف داده‌ها را فراهم می‌نماید
  2. OData protocol که به کلاینت اجازه ایجاد درخواست و پاسخ از سرویس دهنده OData را می‌دهد.
  3. OData client libraries که امکان ساخت ساده‌تر نرم افزار‌ها برای دسترسی به داده‌ها با قرارداد OData را می‌دهد.
  4. OData service سرویس دهنده و امکان دسترسی به داده‌ها را فراهم می‌سازد.
از مزیت‌های OData  می توان به موارد زیر اشاره نمود:
  1. ساده و انعطاف پذیر
  2. سورس باز بودن 
  3. امکان استفاده در سیستم‌های با داده‌های رابطه ای و غیر رابطه ای
  4. امکان استفاده از داده‌ها با منابع ای که آدرس پذیر هستند یعنی  دسترسی از طریق Url
  5. امکان دسترسی هر نوع گیرنده ای به داده ها
  6. امکان نمایش خروجی با فرمت Json  یا Xml 
  7. ...
کتابخانه‌های کار بار OData:
کتابخانه‌های بسیاری برای odata نوشته شده است که امکان استفاده آن را در اکثر زبان‌ها مهیا می‌سازد. 

اما بهترین کتابخانه WCF Data Services است که از سوی مایکروسافت ارائه شده و در اکثر تکنولوژی‌ها و محصولات خود قابلیت استفاده را دارد. WCF Data Services با پیاده سازی قرارداد OData ، توسعه دهندگان را از سطح پایین این قرارداد رهایی ساخته و به راحتی می‌توانند از ساختار شی گرا برنامه خود، در سرویس دهی با OData استفاده نمایند.

کاربرد‌های OData:
OData یک قرارداد سرویس دهی بر روی وب است که به هر نوع گیرنده که امکان دسترسی به وب را داشته باشد، امکان سرویس دهی دارد. به همین خاطر در اکثر برنامه‌های تحت وب یا نرم افرار‌های موبایل که می‌خواهیم اطلاعاتی را مابین سرویس دهنده و گیرنده ردوبدل کنیم حتی زمانیکه platform‌های مختلفی در کار باشند OData بهترین گزینه است. 
در مطالب بعدی با پیاده سازی مثال‌های با استفاده از WCF Data Services بیشتر با OData آشنا خواهید شد. در این اینجا هدف آشنایی اولیه با Odata و کاربردهای آن بود که امیدوارم مفید واقع شده باشد.
مطالب
افزودن خودکار کلاس های WebAPI و SignalR Hub به برنامه در حالت SelfHost
یکی از گزینه‌های میزبانی WebAPI و SignalR حالت SelfHost می‌باشد که روش آن قبلا در مطلب «نگاهی به گزینه‌های مختلف مهیای جهت میزبانی SignalR» توضیح داده شده است.

ابتدا نگاه کوچکی به یک مثال داشته باشیم:
هاب زیر را در نظر بگیرید.
public class MessageHub : Hub
    {
        public void NotifyAllClients()
        {
            Clients.All.Notify();
        } 
}
برای selfHsot کردن از یک برنامه‌ی کنسول استفاده می‌کنیم:
static void Main(string[] args)
        {
            const string baseAddress = "http://localhost:9000/"; // "http://*:9000/";
 
            using (var webapp = WebApp.Start<Startup>(baseAddress))
            {
                Console.WriteLine("Start app...");
 
                var hubConnection = new HubConnection(baseAddress);
                IHubProxy messageHubProxy = hubConnection.CreateHubProxy("messageHub");
 
                messageHubProxy.On("notify", () =>
                {
                    Console.WriteLine();
                    Console.WriteLine("Notified!");
                });
 
                hubConnection.Start().Wait();
 
                Console.WriteLine("Start signalr...");
 
                bool dontExit = true;
                while (dontExit)
                {
                    var key = Console.ReadKey();
                    if (key.Key == ConsoleKey.Escape) dontExit = false;
 
                    messageHubProxy.Invoke("NotifyAllClients");
                }
 
            }
        }
با کلاس start-up ذیل:
public partial class Startup
    {
        public void Configuration(IAppBuilder appBuilder)
        {
            var hubConfiguration = new HubConfiguration()
            {
                EnableDetailedErrors = true
            };
 
            appBuilder.MapSignalR(hubConfiguration);
 
            appBuilder.UseCors(CorsOptions.AllowAll);
 
 
        }
    }
اکنون اگر برنامه را اجرا کنیم، با زدن هر کلید در کنسول، یک پیغام چاپ می‌شود که نشان دهنده صحت کارکرد هاب پیام می‌باشد.
خوب؛ تا الان همه چیز درست کار میکند.

صورت مساله:
معمولا برای منظم کردن و مدیریت بهتر کدهای نرم افزار، آن‌ها را در پروژه‌های مجزا یا در واقع همان class library‌های مجزا نگاه داری میکنیم.
اکنون در برنامه‌ی فوق ، اگر کلاس messageHub را به یک class library دیگر منتقل کنیم و آن را به برنامه‌ی کنسول ارجاع دهیم و برنامه را مجدد اجرا کنیم، با خطای زیر مواجه می‌شویم:
{"StatusCode: 500, ReasonPhrase: 'Internal Server Error', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:\r\n{\r\n  Date: Mon, 27 Oct 2014 09:36:48 GMT\r\n  Server: Microsoft-HTTPAPI/2.0\r\n  Content-Length: 0\r\n}"}
مشکل چیست؟
همانطور که در مطلب «نگاهی به گزینه‌های مختلف مهیای جهت میزبانی SignalR» عنوان شده‌است، «در حالت SelfHost بر خلاف روش asp.net hosting ، اسمبلی‌های ارجاعی برنامه اسکن نمی‌شوند» و طبیعتا مشکل رخ داده شده در بالا از اینجا ناشی می‌شود.

راه حل:
- این کار باید به صورت دستی انجام پذیرد. با افزودن کد زیر به ابتدای برنامه (قبل از شروع هر کدی) اسمبلی‌های مورد نظر افزوده می‌شوند:
AppDomain.CurrentDomain.Load(typeof(MessageHub).Assembly.FullName);
طبیعتا افزودن دستی هر اسمبلی مشکل و در خیلی مواقع ممکن است با خطای انسانی فراموش کردن مواجه شود!
کد خودکار زیر، میتواند تکمیل کننده‌ی راه حل بالا باشد:
class LoadAssemblyHelper
    {
        public static void Load(string searchPattern)
        {
            var path = Assembly.GetExecutingAssembly().Location;
            var entityAssemblies = Directory.GetFiles(Path.GetDirectoryName(path), searchPattern: searchPattern);
            var assemblyNames = entityAssemblies.Select(e => AssemblyName.GetAssemblyName(e)).ToList();
            assemblyNames.ToList().ForEach(e => AppDomain.CurrentDomain.Load(e));
        }
    }
و برای فراخوانی آن در ابتدای برنامه می‌نویسیم:
static void Main(string[] args)
        {
            //AppDomain.CurrentDomain.Load(typeof(MessageHub).Assembly.FullName);
            //AppDomain.CurrentDomain.Load(typeof(MessageController).Assembly.FullName);

            LoadAssemblyHelper.Load("myFramework.*.dll");

            const string baseAddress = "http://*:9000/";
            using (var webapp = WebApp.Start<Startup>(baseAddress))
            {
                ...
            }
        }

نکته‌ی مهم
 این خطا و راه حل آن، در مورد hub‌های signalr و هم controller‌های webapi صادق می‌باشد.
بازخوردهای دوره
بوت استرپ (نگارش 3) چیست؟
از Visual Studio 2012 Update 2 ، ویژوال استودیو دارای یک LESS Editor توکار هست (^ و ^). با استفاده از LESS، یک فایل CSS را می‌شود پارامتری کرد و هربار به این پارامترها و متغیرها، مقادیر متفاوتی را نسبت داد و خروجی CSS گرفت. نسخه‌ی LESS بوت استرپ هم برای همین منظور وجود دارد.
البته اگر نمی‌خواهید در VS.NET این فایل‌ها را ویرایش کرده و خروجی بگیرید، در سایت رسمی آن، امکان سفارشی سازی بوت استرپ و مقدار دهی به متغیرهای آن و نهایتا گرفتن یک خروجی کامل پیش بینی شده‌است.
نظرات اشتراک‌ها
Visual Studio Update 1 RTM منتشر شد
نسخه‌های نصب آفلاین
دات نت 4.6.1 برای توزیع: NDP461-KB3102436-x86-x64-AllOS-ENU.exe
دات نت 4.6.1 برای یکپارچگی با ویژوال استودیوهای 2012 به بعد: NDP461-DevPack-KB3105179-ENU.exe
به روز رسانی اول ویژوال استودیوی 2015: vs2015.1.vsu.iso
نظرات اشتراک‌ها
نحوه دریافت Visual Studio 2012 Update 2 برای نصب آفلاین
دوستان برای اینکه سردرگمی به وجود نیاد توضیح می‌دم.
لینک سوم که حجمش کم هست را من باز کردم از نظر سایز مشکلی ندارد. تفاوت در نوع و میزان فشرده سازی است. ولی با این وجود برای اینکه شکی نباشه همون بسته اصلی را مجدداً به صورت فشرده‌ترین حالت قرار می‌دم. لینک پیشین نیز برای دوستانی که در حال دانلود هستند باقی خواهد ماند.

نظرات اشتراک‌ها
نحوه دریافت Visual Studio 2012 Update 2 برای نصب آفلاین
متاسفانه لینک‌های قبلی رو دانلود کردم و همون طور که فرمودید مشکل داشت. جهت اطمینان خودم این آپدیت را دانلود کردم و با لینک مستقیم برای مدتی به اشتراک میذارم تا دوستان استفاده کنند. این بسته شامل تمام فایل‌های دانلود شده توسط Installer اصلی بدون کوچکترین تغییر می‌باشد که توسط 7z فشرده شده است. با برنامه 7z یا WinRAR قابل استفاده است.

http://dl.forghani.biz/Visual Studio 2012 Update 2 (KB2707250).rar
نظرات اشتراک‌ها
دریافت ویدیوهای کنفرانس Build به کمک پاورشل
کافیست آدرس زیر را در Internet Explorer یا در یک RSS Reader کپی کنید
 http://channel9.msdn.com/Events/Build/2012/RSS/wmvhigh 
هم عنوان، هم توضیحات، هم Comment‌ها و هم لینک مستقیم را می‌توانید یک جا مشاهده کنید، و آنهایی را که می‌خواهید را دانلود کنید
لینک دانلود مستقیم رو هم به Download Manager دهید، تا به بهترین نحو آنرا دریافت کند.
موفق باشید