نظرات مطالب
روش نادرست اعمال دسترسی کاربر به منوها و کنترلهای فرم در windows form ها
مطمعنا بیشتر از 80 درصد نرم افزار‌های داخلی اینگونه طراحی شدن حاضرم از نرم افزار‌های اتوماسیون اداری شرکت‌های مهمی نام ببرم که به این روش کار کردن چون دیدم دارم می‌گم

روشی که اقای رضایی می‌گن درسته، من کمتر تحت ویندوز کار کردم اما همیشه روش اقای رضایی انجام دادم

در کل پست به جایی بود ممنون
نظرات اشتراک‌ها
مقدمات توابع Window در SQL Server 2012
برنامه نویس‌ها سطوح مختلفی دارند. «یکی» کامپوننت می‌اندازه روی فرم حس برنامه نویس بودن پیدا می‌کنه، «یکی» کامپوننت طراحی می‌کنه. «یکی» سرطان می‌گیره تا کار کردن با یک ORM رو یاد بگیره، «یکی» ORM طراحی می‌کنه. «یکی» می‌گرده برای هر کاری ابزار مناسب با اون رو انتخاب و پیدا می‌کنه، «یکی» فکر می‌کنه ابزاری رو که پیدا کرده راه حلی است برای تمام مشکلات بشری.
 
نظرات مطالب
طراحی گردش کاری با استفاده از State machines - قسمت اول
بهتر هست مطلب قسمت دوم رو در همون قسمت دوم پیگیری کنید. اگر قسمت دوم رو مطالعه کرده باشید، یک قسمت، طراحی کلی state machine هست (مثل کلاس BlogPostStateMachine). در قسمت بعدی اون طراحی manager که کار با دیتابیس در اونجا انجام میشه (مثل کلاس BlogPostManager). الان شما مطالب رو مخلوط کردید که نیازی نبوده. در کلاس BlogPostManager جاهایی که کامنت شده، قسمت‌هایی هست که از دیتابیس اطلاعات رو می‌خونه. اون قسمت‌ها رو خودتون پر کنید.
نظرات مطالب
تفاوت بین IQueryable و IEnumerable در حین کار با ORMs
این‌ها بیشتر مباحث طراحی API است. اگر از List استفاده کنید، مصرف کننده کتابخانه شما مجبور است فقط از List استفاده کند. List صرفا یک پیاده سازی خاص از IList است.
اگر از اینترفیس و قرارداد IList استفاده شود، آزادی عمل بیشتری را در اختیار مصرف کننده خواهید گذاشت. در اینجا مصرف کننده می‌تواند از هر پیاده سازی دلخواهی از IList برای کار با API شما استفاده کند. حتی مواردی که در زمان طراحی API اصلی وجود خارجی نداشته‌اند و بعدها پیاده سازی خواهند شد.

نظرات مطالب
MVVM و الگوی ViewModel Locator
سورس ASP.NET MVC‌ در سایت کدپلکس در دسترس هست. این مورد و نحوه طراحی باز آن، تابحال یک مزیت منحصربفردی رو به همراه داشته که میشه گفته بی سابقه هست:
چندین فریم ورک MVC جدید توسط برنامه نویس‌های مستقل برای ASP.NET طراحی شده.
مثلا:
FubuMVC
Nancy
Bistro MVC
OpenRasta
و ...

در کل این‌ها هم می‌تونه ایده‌ای باشه برای کسانی که نمی‌خواهند در چارچوب‌های بسته مایکروسافت کار کنند و علاقمند هستند کنترل بیشتری روی محصول نهایی داشته باشند.
مطالب
معرفی Async Parallel.ForEach در دات نت 6
عموما زمانیکه می‌خواهیم تمام وظایف مدنظر، به صورت موازی اجرا شوند، آن‌ها را Task.WhenAll می‌کنیم. برای مثال 10 هزار درخواست HTTP را به صورت وظایفی، WhenAll می‌کنیم و ... در این حالت ... سرور ریموت، IP شما را خواهد بست! چون کنترلی بر روی تعداد وظیفه‌ی در حالت اجرای موازی وجود ندارد و یک چنین عملی، شبیه به یک حمله‌ی DDOS عمل می‌کند! برای مدیریت بهتر یک چنین مواردی، در دات نت 6 متدهای Parallel.ForEachAsync ارائه شده‌اند تا دیگر نیازی به استفاده از راه‌حل‌های ثالثی که عموما آنچنان بهینه هم نیستند، نباشد.
public static Task ForEachAsync<TSource>(IEnumerable<TSource> source, Func<TSource, CancellationToken, ValueTask> body)
public static Task ForEachAsync<TSource>(IEnumerable<TSource> source, CancellationToken cancellationToken, Func<TSource, CancellationToken, ValueTask> body)
public static Task ForEachAsync<TSource>(IEnumerable<TSource> source, ParallelOptions parallelOptions, Func<TSource, CancellationToken, ValueTask> body)
public static Task ForEachAsync<TSource>(IAsyncEnumerable<TSource> source, Func<TSource, CancellationToken, ValueTask> body)
public static Task ForEachAsync<TSource>(IAsyncEnumerable<TSource> source, CancellationToken cancellationToken, Func<TSource, CancellationToken, ValueTask> body)
public static Task ForEachAsync<TSource>(IAsyncEnumerable<TSource> source, ParallelOptions parallelOptions, Func<TSource, CancellationToken, ValueTask> body)
این مجموعه متدها از ValueTaskها بجای Taskها استفاده می‌کند تا سربار ایجاد Taskها در حلقه‌ها کاهش یابد. همچنین در اینجا degree of parallelism به صورت پیش‌فرض به تعداد هسته‌های سی‌پی تنظیم شده‌است (Environment.ProcessorCount)؛ چون عموما توسعه دهنده‌ها نمی‌دانند که چه عددی را باید برای آن انتخاب کنند. هر چند امکان تنظیم دستی آن‌ها هم وجود دارد (یکی از مهم‌ترین مشکلات کار با WhenAll).

یک مثال: در اینجا می‌خواهیم به صورت موازی، مشخصات کاربرانی از Github را توسط HttpClient دریافت کنیم. هر بار هم فقط می‌خواهیم سه وظیفه اجرا شوند و نه بیشتر
using System.Net.Http.Headers;
using System.Net.Http.Json;
 
var userHandlers = new []  { "users/VahidN", "users/shanselman", "users/jaredpar", "users/davidfowl" };
 
using HttpClient client = new()
{
    BaseAddress = new Uri("https://api.github.com"),
};
client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue("DotNet", "6"));
 
ParallelOptions parallelOptions = new() { MaxDegreeOfParallelism = 3 };
 
await Parallel.ForEachAsync(userHandlers, parallelOptions, async (uri, token) =>
{
    var user = await client.GetFromJsonAsync<GitHubUser>(uri, token); 
    Console.WriteLine($"Name: {user.Name}\nBio: {user.Bio}\n");
});
 
public class GitHubUser
{
    public string Name { get; set; }
    public string  Bio { get; set; }
}
در این مثال، نمونه‌ای از کارکرد متد جدید Parallel.ForEachAsync را مشاهده می‌کنید که اینبار، MaxDegreeOfParallelism آن قابل تنظیم است. یعنی با تنظیم فوق، هربار فقط سه وظیفه به صورت موازی اجرا خواهند شد. البته تنظیم آن به منهای یک، همان حالت WhenAll را سبب خواهد شد؛ یعنی محدودیتی وجود نخواهد داشت.
متد Parallel.ForEachAsync، آرایه‌ای را که باید بر روی آن کار کند، دریافت می‌کند. سپس تنظیمات اجرای موازی آن‌ها را هم مشخص می‌کنیم. در ادامه آن‌ها را در دسته‌های مشخصی، به صورت موازی بر اساس منطقی که مشخص می‌کنیم، اجرا خواهد کرد.


وضعیت امکان اجرای موازی متدهای async همزمان، تا پیش از دات نت 6

<List<T به همراه متد الحاقی ForEach است که می‌تواند یک <Action<T را بر روی المان‌های این لیست، اجرا کند و ... عموما زمانیکه به وظایف async می‌رسیم، به اشتباه مورد استفاده قرار می‌گیرد:
customers.ForEach(c => SendEmailAsync(c));
مثال فوق، با اجرای حلقه‌ی زیر تفاوتی ندارد:
foreach(var c in customers)
{
    SendEmailAsync(c); // the return task is ignored
}
یعنی یک عملیات async، بدون await فراخوانی شده‌است و تا پایان عملیات مدنظر، صبر نخواهد شد. حداقل مشکل آن این است که اگر در این بین استثنایی رخ دهد، هیچگاه متوجه آن نخواهید شد و حتی می‌تواند کل پروسه‌ی برنامه را خاتمه دهد. شاید عنوان کنید که می‌شود این مشکل را به صورت زیر حل کرد:
customers.ForEach(async c => await SendEmailAsync(c));
اما ... این روش هم تفاوتی با قبل ندارد. از این لحاظ که متد ForEach یک <Action<T را دریافت می‌کند که خروجی آن void است. یعنی در نهایت با راه حل دوم، فقط یک async void ایجاد می‌شود که باز هم قابلیت صبر کردن تا پایان عملیات را ندارد. نکته‌ی مهم اینجا است که اجرای موازی آن‌ها توسط متد Parallel.ForEach نیز دقیقا همین مشکل را دارد.
تنها راه حل پذیرفته‌ی شده‌ی چنین عمل async ای، فراخوانی آن‌ها به صورت متداول زیر و بدون استفاده از متد ForEach است:
foreach(var c in customers)
{
   await SendEmailAsync(c);
}
و یا Task.WhenAll کردن آن‌ها، با علم به این موضوع که MaxDegreeOfParallelism آن قابل کنترل نیست (حداقل به صورت استاندارد و بدون نیاز به کتابخانه‌های جانبی). برای مثال بجای نوشتن:
foreach(var o in orders)
{
    await ProcessOrderAsync(o);
}
می‌توان آن‌را به صورت زیر درآورد:
var tasks = orders.Select(o => ProcessOrderAsync(o)).ToList();
await Task.WhenAll(tasks);
در این حالت عملیات ProcessOrderAsync را تبدیل به لیستی از وظایف مدنظر کرده و به متد Task.WhenAll ارسال می‌کنیم تا به صورت موازی اجرا شوند. اما ... اگر 10 هزار Task وجود داشته باشند، کنترلی بر روی تعداد وظایف در حال اجرای موازی وجود نخواهد داشت و این مورد نه تنها سبب بالا رفتن کارآیی نخواهد شد، بلکه می‌تواند سرور را هم با اخلال پردازشی، به علت کمبود منابع در دسترس مواجه کند.

دات نت 6، هم کنترل MaxDegreeOfParallelism را میسر کرده‌است و هم اینکه اینبار نگارش async واقعی Parallel.ForEachAsync را ارائه داده‌است تا دیگر همانند حالت قبلی Parallel.ForEach، به async void‌ها و مشکلات مرتبط با آن‌ها نرسیم.
بازخوردهای دوره
استفاده از async و await در برنامه‌های ASP.NET Web forms 4.5
- اعمال async با اعمال پس زمینه یکی نیستند. اعمال async واقعی از ترد استفاده نمی‌کنند؛ به همین جهت سربار کمی دارند و مقیاس پذیری سیستم را افزایش می‌دهند. زمانیکه از یک عملیات async استفاده می‌کنید، ترد جاری خالی می‌شود و به سرعت به thread pool، برای استفاده از آن جهت پردازش سایر درخواست‌های رسیده هدایت خواهد شد اما اعمال غیر async، ترد جاری را تا پایان پردازش معطل می‌کنند. این تفاوت اصلی و مهم کارهای async و غیر async است.
- انتقال پارامترها به متدهای async مطابق روش C# 5، همانند قبل و مانند روش‌های متداول موجود است. هدف اصلی از طراحی async و await، عادی به نظر رسیدن این اعمال است؛ از دید برنامه نویس.
در مثال بالا، متد public async Task LoadSomeData بدون پارامتر است. اگر نیاز به ارسال پارامتر به آن هست، از روش زیر استفاده کنید:
RegisterAsyncTask(new PageAsyncTask(() => SomeMethod(param1: 1000)));
اشتراک‌ها
سیستم مدیریت هویت غیرمتمرکز: محصول جدید مایکروسافت

در پی همکاری با بنیاد هویت غیرمتمرکز، شرکت مایکروسافت از برنامه خودش برای بهره‌گیری از فناوری بلاک‌چین با هدف حل چالش‌های مدیریت هویت خبر داده است.

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

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

سیستم مدیریت هویت غیرمتمرکز: محصول جدید مایکروسافت
نظرات مطالب
امن سازی برنامه‌های ASP.NET Core توسط IdentityServer 4x - قسمت چهاردهم- آماده شدن برای انتشار برنامه
- یک authorization server هست؛ یک UI هست برای Identity server.  
-  authorization server یک لایه نیست. قرار نیست جزئی از برنامه‌ی شما باشد. یک برنامه‌ی کاملا «مستقل» هست. هدف اصلی آن هم همین مستقل بودن و نقش تامین هویت مرکزی را بازی کردن هست و گرنه اگر قرار باشد این‌ها با هم یکی شوند، شاید بهتر باشد از ASP.NET Core Identity استفاده کنید. 
- این روش برای شرکتی طراحی شده که یک برنامه‌ی حسابداری دارد، یک برنامه‌ی مجزای منابع انسانی و مدیریت کارمندان، یک برنامه‌ی مجزای مالی و حقوق و دستمزد، یک برنامه‌ی مجزای حضور و غیاب، یک برنامه‌ی مجزای اعلانات شرکت و غیره. هر کدام از این برنامه‌ها هم یک دیتابیس مستقل دارند و قرار نیست تعاریف کاربران و اطلاعات و نقش‌های آن‌ها در بانک‌های اطلاعاتی هر کدام از این برنامه‌ها تکرار شوند. اینجا است که «برنامه‌ی مستقل» authorization server مرکزی معنا پیدا می‌کند.
مطالب
چگونه تشخیص دهیم UI Virtualization در WPF خاموش شده است؟
در مطلب «بهبود کارآیی کنترل‌های لیستی WPF در حین بارگذاری تعداد زیادی از رکوردها» عنوان شد که در حالت فعال بودن UI Virtualization، فقط به تعداد ردیف‌های نمایان، اشیاء متناظری به یک کنترل لیستی اضافه می‌شوند و حالت برعکس آن زمانی است که ابتدا کلیه اشیاء بصری یک لیست تولید شده و سپس لیست نهایی نمایش داده می‌شود.

سؤال: چگونه می‌توان تعداد اشیاء اضافه شده به Visual tree یک کنترل لیستی را شمارش کرد؟

شبیه به افزونه FireBug فایرفاکس، برنامه‌ای به نام Snoop نیز جهت WPF تهیه شده است که با تزریق خود به درون پروسه برنامه، امکان بررسی ساختار Visual tree کل یک صفحه را فراهم می‌کند. برای دریافت آن به آدرس ذیل مراجعه نمائید:

پس از دریافت، ابتدا مثال انتهای بحث «بهبود کارآیی کنترل‌های لیستی WPF در حین بارگذاری تعداد زیادی از رکوردها» را اجرا کرده و سپس برنامه Snoop را نیز جداگانه اجرا نمائید. اگر نام برنامه WPF مورد نظر، در لیست برنامه‌های تشخیص داده شده توسط Snoop ظاهر نشد، یکبار بر روی دکمه Refresh آن کلیک نمائید. پس از آن برنامه نمایش لیست‌ها را در Snoop انتخاب کرده و دکمه کنار آیکن minimize کردن Snoop را کشیده و بر روی پنجره برنامه رها کنید. شکل زیر ظاهر خواهد شد:


بله. همانطور که ملاحظه می‌کنید، در برگه Slow version به علت فعال نبودن مجازی سازی UI، تعداد اشیاء موجود در Visual tree کنترل لیستی، بالای 10 هزار مورد است. به همین جهت بارگذاری آن بسیار کند انجام می‌شود.
اکنون همین عملیات کشیدن و رها کردن دکمه بررسی Snoop را بر روی برگه دوم برنامه انجام دهید:


در اینجا چون مجازی سازی UI فعال شده است، فقط به تعداد ردیف‌های نمایان به کاربر، اشیاء لازم جهت نمایش لیست، تولید و اضافه شده‌اند که در اینجا فقط 188 مورد است و در مقایسه با 10 هزار مورد برگه اول، بسیار کمتر می‌باشد و بدیهی است در این حالت مصرف حافظه برنامه بسیار کمتر بوده و همچنین سرعت نمایش لیست نیز بسیار بالا خواهد بود.