نظرات مطالب
تکمیل کلاس DelegateCommand
راهی برای پیاده سازی این موضوع در سیلورلایت وجود دارد؟!!!
مطالب
استفاده از jQuery Ajax جهت تعیین اعتبار یک فرم

فرض کنید تعیین اعتبار یکی از فیلدهای فرم نیاز به انجام محاسباتی در سمت سرور دارد و این‌کار را می‌خواهیم با استفاده از jQuery Ajax‌ انجام دهیم. مشکلی که در اینجا وجود دارد، این است که A در Ajax به معنای asynchronous است. یعنی زمانیکه کاربر دکمه submit را فشرد، دیگر برنامه منتظر این نخواهد شد که پاسخ کامل دریافت شود ، سایر پردازش‌ها صورت گیرد و سپس فرم را به سرور ارسال نماید (شبیه به ایجاد یک ترد جدید در برنامه‌های ویندوزی). مثال زیر را در نظر بگیرید:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="TestCustomValidation.aspx.cs"
Inherits="TestJQueryAjax.TestCustomValodation" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>

<script src="js/jquery.js" type="text/javascript"></script>

<script type="text/javascript">
function validate() {
var number1 = $("#<%=txtNumber1.ClientID %>").val();
var number2 = $("#<%=txtNumber2.ClientID %>").val();
var result = false;
$.ajax({
type: "POST",
url: 'AjaxSrv.asmx/ValidateIt',
data: '{"number1":' + number1 + ',"number2":' + number2 + '}',
contentType: "application/json; charset=utf-8",
dataType: "json",
success:
function(msg) {
if (msg.d) {
result = true;
alert('بسیار خوب');
}
else {
result = false;
alert('دوباره سعی کنید');
}
},
error:
function(XMLHttpRequest, textStatus, errorThrown) {
result = false;
alert("خطایی رخ داده است");
}
});
//debugger;
return result;
}
</script>

</head>
<body>
<form id="form1" runat="server">
<div>
number 1 :
<asp:TextBox runat="server" ID="txtNumber1" />
<br />
number 2 :
<asp:TextBox runat="server" ID="txtNumber2" />
<br />
<asp:Button ID="btnSubmit" Text="Submit" UseSubmitBehavior="false" runat="server"
OnClientClick="if(!validate()){ return false;}" OnClick="btnSubmitClick" />
</div>
</form>
</body>
</html>

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

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Web.Script.Services;

namespace TestJQueryAjax
{
/// <summary>
/// Summary description for AjaxSrv
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
[ScriptService]
public class AjaxSrv : System.Web.Services.WebService
{
[WebMethod(EnableSession = true)]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public bool ValidateIt(int number1, int number2)
{
return number1 * number2 == 10;
}
}
}
در این مثال هنگام submit ، عملیات اعتبار سنجی با توجه به وضعیت asynchronous عملیات Ajax ، تمام و کمال رخ نداده ، یا اعتبار سنجی انجام نمی‌شود و یا پیغام خطایی را دریافت خواهیم کرد.

راه حل چیست؟
راه حل‌های فضایی بسیاری را در وب در این مورد می‌توان پیدا کرد؛ اما راه حل استاندارد آن در این حالت ویژه، استفاده از Ajax در حالت غیرهمزمان است. یعنی این فریم ورک Ajax را وادار کنیم که تا پایان عملیات مورد نظر، منتظر بماند و سپس فرم را ارسال کند. برای این منظور تنها کافی است یک سطر زیر را پیش از فراخوانی تابع Ajax ، اضافه و فراخوانی نمائیم:

$.ajaxSetup({async: false}) ;
نکته:
UseSubmitBehavior دکمه ما را به شکل زیر رندر می‌کند (دکمه به یک button معمولی (بجای حالت submit) تبدیل شده و سپس یک doPostBack را اضافه خواهد کرد):

<input id="btnSubmit" type="button" onclick="if(!validate()){ return false;};__doPostBack('btnSubmit','')" value="Submit" name="btnSubmit"/>


نظرات مطالب
طراحی افزونه پذیر با ASP.NET MVC 4.x/5.x - قسمت اول
از مطلب «تهیه XML امضاء شده جهت تولید مجوز استفاده از برنامه» ایده بگیرید. یک متد GetLicense به اینترفیس IPlugin اضافه کنید و در آن مجوز ارائه شده توسط افزونه را در برنامه‌ی اصلی بررسی کنید (در کلاس PluginsStart و همچنین فایل PluginsMenu.cshtml_). فقط کسانی می‌توانند «XML امضاء شده» تولید کنند که دسترسی به کلیدهای خصوصی و امن شما را داشته باشند.  
مطالب
پردازش توالی توالی‌ها در Reactive extensions
به صورت پیش فرض، Rx هر بار تنها یک مقدار را بررسی می‌کند. اما گاهی از اوقات نیاز است تا در هربار، بیشتر از یک مقدار دریافت و پردازش شوند. برای این منظور Rx متدهای الحاقی ویژه‌ای را به نام‌های Buffer ،Scan و Window تدارک دیده‌است تا بتواند از یک توالی، چندین توالی را تولید کند (توالی توالی‌ها = Sequence of sequences).


متد Scan

فرض کنید قصد دارید تعدادی عدد را با هم جمع بزنید. برای اینکار عموما عدد اول با عدد دوم جمع زده شده و سپس حاصل آن با عدد سوم جمع زده خواهد شد و به همین ترتیب تا آخر توالی. کار متد Scan نیز دقیقا به همین نحو است. هربار که قرار است توالی پردازش شود، حاصل عملیات مرحله‌ی قبل را در اختیار مصرف کننده قرار می‌دهد.
در مثال ذیل، قصد داریم حاصل جمع اعداد موجود در آرایه‌ای را بدست بیاوریم:
var sequence = new[] { 12, 3, -4, 7 }.ToObservable();
var runningSum = sequence.Scan((accumulator, value) =>
{
    Console.WriteLine("accumulator {0}", accumulator);
    Console.WriteLine("value {0}", value);
    return accumulator + value;
});
runningSum.Subscribe(result => Console.WriteLine("result {0}\n", result));
با این خروجی
result 12

accumulator 12
value 3
result 15

accumulator 15
value -4
result 11

accumulator 11
value 7
result 18
در اولین بار اجرای متد Subscribe، کار مقدار دهی accumulator با اولین عنصر آرایه صورت می‌گیرد.
در دفعات بعدی، مقدار این accumulator با عدد جاری جمع زده شده و حاصل این عملیات در تکرار آتی، مجددا توسط accumulator قابل دسترسی خواهد بود.

یک نکته: اگر علاقمند باشیم که مقدار اولیه‌ی accumulator، اولین عنصر توالی نباشد، می‌توان آن‌را توسط پارامتر seed متد Scan مقدار دهی کرد:
 var runningSum = sequence.Scan(seed: 10, accumulator: (accumulator, value) =>


متد Buffer

متد بافر، کار تقسیم یک توالی را به توالی‌های کوچکتر، بر اساس زمان، یا تعداد عنصر مشخص شده، انجام می‌دهد. برای مثال در برنامه‌های دسکتاپ شاید نیازی نباشد تا به ازای هر عنصر توالی، یکبار رابط کاربری را به روز کرد. عموما بهتر است تا تعداد مشخصی از عناصر یکجا پردازش شده و نتیجه‌ی این پردازش به تدریج نمایش داده شود.
var sequence = Enumerable.Range(1, 200)
                 .ToObservable()
                 .Buffer(count: 10);

sequence.Subscribe(onNext: numbers =>
{
   Console.WriteLine(numbers.Sum());
});
در اینجا نحوه‌ی استفاده از متد بافر را به همراه مشخص کردن تعداد اعضای بافر ملاحظه می‌کنید. هربار که onNext متد Subscribe فراخوانی شود، 10 عنصر از توالی را در اختیار خواهیم داشت (بجای یک عنصر حالت متداول بافر نشده).
به این ترتیب می‌توان فشار حجم اطلاعات ورودی با فرکانس بالا را کنترل کرد و در نتیجه از منابع موجود بهتر استفاده نمود. برای مثال اگر می‌خواهید عملیات bulk insert را انجام دهید، می‌توان بر اساس یک batch size مشخص، گروه گروه اطلاعات را به بانک اطلاعاتی اضافه کرد تا فشار کار کاهش یابد.

همینکار را بر اساس زمان نیز می‌توان انجام داد:
 var sequence = Enumerable.Range(1, 200)
                   .ToObservable()
                   .Buffer(timeSpan: TimeSpan.FromSeconds(2));
در مثال فوق هر 2 ثانیه یکبار، مجموعه‌ای از عناصر به متد onNext ارسال خواهند شد.


متد Window

متد Window نیز دقیقا همان پارامترهای متد بافر را قبول می‌کند. با این تفاوت که هربار، یک توالی obsevable را به متد onNext ارسال می‌کند.
نوع numbers پارامتر onNext، در حین بکارگیری متد بافر در مثال‌های فوق، IList of int است. اما اگر متدهای Buffer را تبدیل به متد Window کنیم، اینبار نوع numbers، معادل IObservable of int خواهد شد.
 var sequence = Enumerable.Range(1, 200)
                           .ToObservable()
                           .Window(timeSpan: TimeSpan.FromSeconds(2));

sequence.Subscribe(onNext: numbers =>
{
       numbers.Subscribe(onNext: number => Console.WriteLine(number));
});


چه زمانی باید از Buffer استفاده کرد و چه زمانی از Window؟

در متد بافر، به ازای هر توالی که به پارامتر onNext ارسال می‌شود، یکبار وهله‌ی جدیدی از توالی مدنظر در حافظه ایجاد و ارسال خواهد شد. در متد Window صرفا اشاره‌گرهایی به این توالی را در اختیار داریم؛ بنابراین مصرف حافظه‌ی کمتری را شاهد خواهیم بود. متد Window بسیار مناسب است برای اعمال aggregation. مثلا اگر نیاز است جمع، میانگین، حداقل و حداکثر عناصر دریافتی محاسبه شوند، بهتر است از متد Window استفاده شود که نهایتا قابلیت استفاده از متدهای الحاقی Sum و Max و Min را به همراه دارد. با این تفاوت که حاصل این‌ها نیز یک IObservable است که باید Subscribe آن‌را برای دریافت نتیجه فراخوانی کرد:
 var sequence = Enumerable.Range(1, 200)
                          .ToObservable()
                          .Window(10);

sequence.Subscribe(onNext: numbers =>
{
     numbers.Sum().Subscribe(onNext: number => Console.WriteLine(number));
});
در این حالت متد Window، برخلاف متد Buffer، توالی numbers را هربار کش نمی‌کند و به این ترتیب می‌توان به مصرف حافظه‌ی کمتری رسید.


کاربردهای دنیای واقعی

در اینجا دو مثال از بکارگیری متد Buffer را جهت پردازش مجموعه‌های عظیمی از اطلاعات و نمایش همزمان آن‌ها در رابط کاربری ملاحظه می‌کنید.
مثال اول: فرض کنید قصد دارید تمام فایل‌های درایو C خود را توسط یک TreeView نمایش دهید. در این حالت نباید رابط کاربری برنامه در حالت هنگ به نظر برسد. همچنین به علت زیاد بودن تعداد فایل‌ها و نمایش همزمان آن‌ها در UI، نباید CPU Usage برنامه تا حدی باشد که در کار سایر برنامه‌ها اخلال ایجاد کند. در این مثال‌ها با استفاده از Rx و متد بافر آن، هربار مثلا 1000 آیتم را بافر کرده و سپس یکجا در TreeView نمایش می‌دهند. به این ترتیب دو شرط یاد شده محقق می‌شوند.
The Rx Framework By Example

مثال دوم: خواندن تعداد زیادی رکورد از بانک اطلاعاتی به همراه نمایش همزمان آن‌ها در UI بدون اخلالی در کار سیستم و همچنین هنگ کردن برنامه.
Using Reactive Extensions for Streaming Data from Database
مطالب
حذف هدرهای مربوط به وب سرور از یک برنامه‌ی ASP.Net

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



امکان تغییر و حذف هدرهای مربوط به response تنها با استفاده از امکانات IIS7 میسر است (در حالت integrated pipeline) و IIS6 چنین اجازه‌ای را به ASP.Net نمی‌دهد.
برای این منظور یک پروژه‌ی جدید، به نام SecurityMdl از نوع class library را ایجاد کرده و دو فایل SecurityMdl.cs و CRemoveHeader.cs را به آن اضافه خواهیم کرد:

//SecurityMdl.cs
using System;
using System.Web;

namespace SecurityMdl
{
public class SecurityMdl : IHttpModule
{
public void Init(HttpApplication app)
{
app.PreSendRequestHeaders += app_PreSendRequestHeaders;
}

static void app_PreSendRequestHeaders(object sender, EventArgs e)
{
CRemoveHeader.CheckPreSendRequestHeaders(sender);
}

public void Dispose() { }
}
}


در این Http module ، با تغییر اطلاعات دریافتی در روال رخ‌داد گردان PreSendRequestHeaders می‌توان به مقصود رسید:

//CRemoveHeader.cs
using System;
using System.Collections.Generic;
using System.Web;

namespace SecurityMdl
{
class CRemoveHeader
{
private static readonly List<string> _headersToRemoveCache
= new List<string>
{
"X-AspNet-Version",
"X-AspNetMvc-Version",
"Server"
};

public static void CheckPreSendRequestHeaders(Object sender)
{
//capture the current request
var currentResponse = ((HttpApplication)sender).Response;

//removing headers
//it only works with IIS 7.x's integrated pipeline
_headersToRemoveCache.ForEach(h => currentResponse.Headers.Remove(h));

//modify the "Server" Http Header
currentResponse.Headers.Set("Server", "Test");
}
}
}
در اینجا علاوه بر حذف هدرهای ذکر شده در headersToRemoveCache ، هدر Server در پایان کار با یک مقدار جدید نیز ارسال می‌گردد.
و نهایتا برای استفاده از آن (علاوه بر افزودن ارجاعی به این ماژول جدید) چند سطر زیر را باید به وب کانفیگ برنامه اضافه کرد:

<system.webServer>
<modules>
<add name="SecurityMdl" type="SecurityMdl.SecurityMdl, SecurityMdl"/>
</modules>

با استفاده از این روش تمامی هدرهای مورد نظر بجز هدری به نام X-Powered-By حذف خواهند شد. برای حذف هدر مربوط به X-Powered-By که توسط خود IIS مدیریت می‌شود باید موارد زیر را به web.config برنامه اضافه کرد:

<system.webServer>
<httpProtocol>
<customHeaders>
<remove name="X-Powered-By"/>
</customHeaders>
</httpProtocol>
و یا می‌توان توسط خود IIS‌ نیز این مورد را تغییر داد یا کلا حذف نمود:




اکنون پس از این تغییرات حاصل کار و هدر نهایی دریافت شده از response یک برنامه‌ی ASP.net به شکل زیر درخواهد آمد:





برای مطالعه‌ی بیشتر
Remove the X-AspNet-Version header
Cloaking your ASP.NET MVC Web Application on IIS 7
IIS 7 - How to send a custom "Server" http header
Removing Unnecessary HTTP Headers in IIS and ASP.NET
Remove X-Powered-By: ASP.NET HTTP Response Header

مطالب
اسکرول روان لیست‌های مجازی سازی شده در WPF 4.5
جهت «بهبود کارآیی کنترل‌های لیستی WPF در حین بارگذاری تعداد زیادی از رکوردها» توصیه شده‌است که مجازی سازی UI فعال گردد. به این ترتیب بجای تولید یکباره‌ی برای مثال 1000 ردیف، تنها 10 ردیفی که نمایان هستند تولید می‌شوند. بنابراین مصرف حافظه و سرعت برنامه به نحو قابل ملاحظه‌ای افزایش خواهد یافت. اما ... این مجازی سازی، اسکرول مطلوبی ندارد و بریده بریده به نظر می‌رسد.


خاصیت‌های جدید VirtualizingPanel در دات نت 4.5

تمام کنترل‌های مشتق شده‌ی از ListBox مانند ListView و امثال آن، در WPF 4.5 امکان تنظیم یک چنین خواصی را یافته‌اند:
<ListBox ItemsSource="{Binding Persons}"
        VirtualizingPanel.IsVirtualizing="True"
        VirtualizingPanel.ScrollUnit="Pixel"
        VirtualizingPanel.IsVirtualizingWhenGrouping="True"
        VirtualizingPanel.CacheLength="100"        
        VirtualizingPanel.CacheLengthUnit="Pixel"/>
در WPF 4.5 پس از نمایش تعداد ردیف‌های قابل ملاحظه‌ی توسط کاربر، سیستم کش خودکاری با حق تقدم پایین فعال شده و آیتم‌هایی را که هنوز نمایان نیستند، ایجاد و کش می‌کند. به این ترتیب کاربر با اسکرول به سمت پایین یا بالا، کندی رندر یا بریده بریده به نظر رسیدن اسکرول را حس نخواهد کرد.
در اینجا می‌توان دو خاصیت CacheLength و CacheLengthUnit را مقدار دهی کرد. مقدار پیش فرض CacheLength مساوی 1.1 است. CacheLengthUnit می‌تواند یکی از مقادیر Pixel, Item یا Page را بپذیرد. هر Page در اینجا بر اساس اندازه‌ی viewport یا قسمت نمایان لیست، تعریف می‌شود. مقدار پیش فرض آن نیز Item است.
همچنین در اینجا می‌توان ScrollUnit را نیز تنظیم کرد که مقادیر Item یا Pixel را می‌پذیرد. حالت پیش فرض آن Item است؛ به این معنا که اگر ردیفی کاملا در viewport جای نگرفت، نمایش داده نمی‌شود. این مورد را با تنظیم مقدار ScrollUnit به Pixel می‌توان بهبود بخشید.
IsVirtualizingWhenGrouping سبب فعال سازی مجازی سازی حتی در حالت گروه بندی اطلاعات می‌گردد. به صورت پیش فرض اگر گروه بندی فعال شود، دیگر مجازی سازی رخ نخواهد داد.


فعال سازی قابلیت‌های دات نت 4.5 در برنامه‌های WPF 4

اگر برنامه‌ی WPF 4 خود را فعلا قصد ندارید به دات نت 4.5 ارتقاء دهید، با توجه به اینکه اگر کاربر دات نت 4.5 را نصب کرده باشد، برنامه‌ی شما به صورت خودکار همانند یک برنامه‌ی WPF 4.5 رفتار می‌کند (دات نت 4.5 جایگزین دات نت 4 می‌شود)، می‌توان با اندکی Reflection این قابلیت‌ها را در صورت وجود، فعال کرد:
using System;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;

namespace DNTProfiler.Common.Behaviors
{
    /// <summary>
    /// Smooth scrolling VirtualizingStackPanels, without sacrificing virtualization.
    /// </summary>
    public static class PixelBasedScrollingBehavior
    {
        private static readonly MethodInfo _setScrollUnit = typeof(VirtualizingPanel)
            .GetMethod("SetScrollUnit", BindingFlags.Public | BindingFlags.Static);

        private static readonly MethodInfo _setCacheLengthUnit = typeof(VirtualizingPanel)
            .GetMethod("SetCacheLengthUnit", BindingFlags.Public | BindingFlags.Static);

        private static readonly MethodInfo _setCacheLength = typeof(VirtualizingPanel)
            .GetMethod("SetCacheLength", BindingFlags.Public | BindingFlags.Static);

        public static bool GetIsEnabled(DependencyObject obj)
        {
            return (bool)obj.GetValue(IsEnabledProperty);
        }

        public static void SetIsEnabled(DependencyObject obj, bool value)
        {
            obj.SetValue(IsEnabledProperty, value);
        }

        public static readonly DependencyProperty IsEnabledProperty =
            DependencyProperty.RegisterAttached("IsEnabled", typeof(bool), typeof(PixelBasedScrollingBehavior), new UIPropertyMetadata(false, handleIsEnabledChanged));

        private static void handleIsEnabledChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            var listView = obj as ListView;
            if (listView == null)
            {
                throw new InvalidOperationException("This behavior can only be attached to a ListView.");
            }

            if (_setScrollUnit != null)
            {
                // It's .NET 4.5
                _setScrollUnit.Invoke(listView, new object[] { listView, /*Pixel*/ 0 });
            }

            if (_setCacheLengthUnit != null)
            {
                // It's .NET 4.5
                _setCacheLengthUnit.Invoke(listView, new object[] { listView, /*Pixel*/ 0 });
            }


            if (_setCacheLength != null)
            {
                // It's .NET 4.5
                var type = Type.GetType("System.Windows.Controls.VirtualizationCacheLength, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
                if (type == null) return;
                var instance = Activator.CreateInstance(type, 100.0);

                _setCacheLength.Invoke(listView, new[] { listView, instance });
            }
        }
    }
}
در اینجا با تعریف یک Attached property جدید، خواصی مانند ScrollUnit، CacheLengthUnit و CacheLength توسط Reflection یافت خواهند شد. اگر مقدار آن‌ها نال نباشند، یعنی برنامه‌ی دات نت 4 در سیستمی که بر روی آن دات نت 4.5 نصب است، در حال اجرا می‌باشد. بنابراین در این حالت می‌توان اسکروال مبتنی بر Pixel را فعال کرد تا برنامه اسکرول روان‌تری را پیدا کند.
برای استفاده از آن خواهیم داشت:
<ListView ItemsSource="{Binding}"
               behaviors:PixelBasedScrollingBehavior.IsEnabled="True">
نظرات مطالب
Portable Class Library چیست و چگونه از آن استفاده کنیم؟
دوستان، اصلا مطلب من رو مطالعه کردید ؟
بله، مسلما وقتی کدی در سیلورلایت کار نکنه، یعنی کار نمی‌کنه، حالا به هر روشی، مگه این که شما بفرمایید Portable Library قابلیت جدیدی رو برای مثال به سیلورلایت اضافه می‌کنه که "در حالت عادی" در دسترس نیست.
وقتی پروژه شما Silverlight و NET. اش جدا باشد، Silverlight ای اون هم از بقیه Silverlight ای‌های موجود در اینترنت می‌تونه استفاده کنه ( برای مثال WCF Data Services Client Library )، و هم می‌تونه از Portable‌های که Silverlight شون تیک خورده باشه استفاده کنه، مثل Post Sharp
اما وقتی شما به جای Add As Link از Portable استفاده می‌کنید، با این که در تعامل با WCF Data Services یک دست خط کد کاملا یکسان دارید، نمی‌تونید تو پروژه تون از WCF Data Services استفاده کنید.
یک وقت هست، شما از MVVM Light Toolkit دارید استفاده می‌کنید، کد WPF و Silverlight تون هم کاملا مشابه هستش، در این جا کار شما با Add As Link راه می‌افته، ولی با Portable نه
در حالت Portable شما System.Linq رو دارید، خوبه، در Add As Link هم اون رو دارید، ولی Expression.Interactivity رو فقط در Add As Link دارید، با این که کد می‌تونه 100% یک دست باشه
موفق و پایدار باشید
نظرات مطالب
EF Code First #12
- یک Context در EF باید طول عمر کوتاهی داشته باشد. سینگلتون تعریف کردن آن یعنی زنده نگه داشتن آن در طول عمر برنامه. در یک برنامه وب به این ترتیب اگر جایی کاربری به مشکلی برخورد، چون یک Context در این حالت بیشتر وجود نخواهد داشت، تمام خطاهای آن کاربر به سایر کاربران نیز منعکس می‌شود. همچنین Context به صورت thread safe طراحی نشده و به این ترتیب به مشکلات تخریب اطلاعات در برنامه‌های چند کاربره نیز برخواهید خورد.
- در مطلب فوق به ازای هر درخواست یک Context ایجاد می‌شود (مقدمه بحث). Context در طول عمر یک درخواست کاربری خاص، زنده نگه داشته شده و بعد در پایان کار آن درخواست Dispose می‌شود. نه فقط بحث مدیریت اتصالات در اینجا مطرح است، بحث مدیریت یک تراکنش واحد در طول عمر یک درخواست نیز باید درنظر گرفته شود.

چند پیشنهاد:
- یکبار مطلب جاری را مطالعه کنید.
- یکبار وقت بگذارید نظرات آن‌را هم بررسی کنید. در مورد سینگلتون یا حتی Contextهای استاتیک و امثال آن قبلا بحث شده.
- یکبار دوره پیشنیاز این مطلب را مطالعه کنید: «بررسی مفاهیم معکوس سازی وابستگی‌ها و ابزارهای مرتبط با آن»
- یکبار دوره خاص برنامه‌های دسکتاپ طراحی شده با این الگو را هم مطالعه کنید: «طراحی یک فریم ورک برای کار با WPF و EF Code First توسط الگوی MVVM»
- نگاهی هم به یک پروژه کامل ASP.NET MVC که با درنظر گرفتن الگوی مطرح شده در این بحث تهیه شده، داشته باشید: «سیستم مدیریت محتوای IRIS»

این مبحث باز شده‌اش بالای 20 قسمت است.
مطالب
خلاصه‌ای در مورد SQL Server CE

SQL Server CE برای اولین بار جهت استفاده در SmartPhones طراحی شد؛ جزو خانواده‌ی Embedded databases قرار می‌گیرد و این مزایا را دارد:
- نیازی به نصب ندارد و از چند DLL تشکیل شده است (برای مثال جهت استفاده در کارهای تک کاربره‌ی قابل حمل ایده‌آل است).
- رایگان است (جهت استفاده در کارهای تجاری و غیرتجاری).
- حجم کمی دارد (جمعا کمتر از دو مگابایت).
- پروایدر ADO.NET آن موجود است (توسط فضای نام System.Data.SqlServerCe که به کمک اسمبلی System.Data.SqlServerCe.dll قرار گرفته در مسیر C:\Program Files\Microsoft SQL Server Compact Edition\v3.5\Desktop ارائه می‌شود).
- با کمک ORM هایی مانند Entity framework و یا NHibernate نیز می‌توان با آن کار کرد.
- نسخه‌ی 4 نهایی آن که قرار است در زمان ارائه‌ی SP1 مربوط به VS.NET 2010 ارائه شود، جهت استفاده در برنامه‌های ASP.NET (برنامه‌های چند کاربره) ایی که تعداد کاربر کمی دارند، بهینه سازی شده و این مورد یک مزیت مهم نسبت به SQLite است که اساسا با تردهای همزمان جهت کار با بانک اطلاعاتی مشکل دارد.
- امکان گذاشتن کلمه‌ی عبور بر روی بانک اطلاعاتی آن وجود دارد که سبب رمزنگاری خودکار آن نیز خواهد شد (این مورد به صورت پیش فرض در SQLite پیش بینی نشده و جزو مواردی که است که باید برای آن هزینه کرد). الگوریتم رمزنگاری آن به صورت رسمی معرفی نشده، ولی به احتمال زیاد AES می‌باشد.
- از ADO.NET Sync Framework پشتیبانی می‌کند.

ملاحظات:
- به آن می‌توان به صورت نسخه‌ی تعدیل شده‌ی SQL Server 2000 با توانایی‌های کاهش یافته نگاه کرد. در آن خبری از رویه‌های ذخیره شده، View ها ، Full text search ، CLR Procs، CLR Triggers و غیره نیست (سطح توقع را باید در حد همان 2 مگابایت پایین نگه داشت!). لیست کامل : (+)
- Management studio مربوط به SQL Server 2005 به هیچ عنوان از آن پشتیبانی نمی‌کند و تنها نسخه‌ی 2008 است که نگارش 3 و نیم آن‌را پشتیبانی می‌کند آن هم نه با توانایی‌هایی که جهت کار با SQL Server اصلی وجود دارد. مثلا امکان rename یک فیلد را ندارد و باید برای اینکار کوئری نوشت. خوشبختانه یک سری پروژه‌ی رایگان در سایت CodePlex این نقایص را پوشش داده‌اند؛ برای مثال : ExportSqlCe
- از آنجائیکه DLL های SQL CE از نوع Native هستند، باید دقت داشت که حین استفاده از آن‌ها در دات نت فریم ورک اگر platform target قسمت build برنامه بر روی ALL CPU تنظیم شده باشد، برنامه به احتمال زیاد در سیستم‌های 64 بیتی کرش خواهد کرد (اگر در حین توسعه برنامه از DLL‌های بومی 32 بیتی آن استفاده شده باشد). بنابراین نیاز است DLL های 64 بیتی را به صورت جداگانه جهت سیستم‌های 64 بیتی ارائه داد. اطلاعات بیشتر: (+) و (+) و (+)
- Entity framework یک سری از قابلیت‌های این بانک اطلاعاتی را پشتیبانی نمی‌کند. برای مثال اگر یک primary key از نوع identity را تعریف کردید، برنامه کار نخواهد کرد! لیست مواردی را که پشتیبانی نمی‌شوند، در این آدرس می‌توان مشاهده کرد.

و اخبار مرتبط با SQL CE را در این بلاگ می‌توانید دنبال کنید.