Top Functional Programming Languages to Learn in 2024
Functional programming languages encourage a different approach to solving problems, often leading to cleaner and more predictable code. By focusing on pure functions, avoiding side effects, and utilizing higher-order functions, functional programming can improve code quality and reduce bugs. Additionally, these languages are well-suited for concurrent and parallel programming, making them valuable in modern, high-performance computing environments.
NET 8.0.402. منتشر شد
Let's start our journey together to build beautiful native cross-platform apps for iOS, Android, macOS, and Windows with .NET MAUI, C#, and Visual Studio! In this full workshop, I will walk you through everything you need to know about .NET MAUI and building your very first app. You will learn the basics including how to build user interfaces with XAML, how MVVM and data binding simplify development, how to navigate between pages, access platform features like geolocation, optimize data collections, and theme your app for light theme and dark theme. This course has everything you need to learn the basics and set you up for success when building apps with .NET MAUI!
Chapters:
00:00:00 - Intro to the .NET MAUI Workshop
00:04:10 - What is .NET MAUI & How to Install
00:06:25 - Workshop overview
00:08:00 - First .NET MAUI app & Architecture (slides)
00:21:40 - Get code to build your first .NET MAUI app
00:25:00 - .NET MAUI Project Walkthrough
00:29:40 - Start to build first .NET MAUI app
00:56:48 - Intro to MVVM (slides)
01:09:30 - Implementing INotifyPropertyChanged
01:22:30 - .NET Community Toolkit for MVVM (Source Generators)
01:32:30 - HTTP REST Calls & JSON Deserialization
01:43:00 - ICommand in .NET MAUI
01:59:30 - Create our UI with XAML & MVVM
02:16:20 - Navigation in .NET MAUI (slides)
02:25:20 - Implementing Navigation in .NET MAUI & Passing Parameters
02:46:00 - Building a details UI with XAML & MVVM
02:54:10 - Modal, Back Navigation, & More
02:58:20 - Access Platform APIs in .NET MAUI (slides)
03:02:53 - Platform API Integration - Connectivity
03:08:30 - Geolocation & Permissions Implementation
03:18:50 - Open Map Integration
03:22:40 - Platform Specifics - iOS Safe Area
03:25:50 - CollectionView & RefreshView Overview (slides)
03:34:00 - Implementing Pull-to-Refresh
03:40:00 - CollectionView Layouts - Grids and more
03:41:30 - CollectionView EmptyView
03:45:00 - App Resources, Styles, and Themes (slides)
03:56:20 - Implementing Light & Dark Mode
04:06:00 - Thanks, wrap-up, and resources
کوکیها به اندازهی خود اینترنت قدیمی هستند و تا سالها، تنها گزینهی شخصی سازی تجربهی کاربری در وب و انتقال آن از یک صفحه به صفحهی دیگری بهشمار میآمدند؛ به این نوع کوکیها، First-party cookies هم میگویند و توسط خود سایت ارائه دهندهی محتوا و برنامهها، تنظیم میشوند. در مقابل آن، third-party cookies یا کوکیهای ثالث هم وجود دارند که از طریق دومین دیگری بجز دومین اصلی برنامه، ارائه و تنظیم میشوند؛ به همین جهت به آنها Cross-site cookies هم میگویند. یکی از اهداف کوکیهای ثالث، ردیابی فعالیت کاربران در بین سایتهای مختلف است و این روزها به علت سوء استفادههای زیادی که از آنها میشوند، یکی از وسایل به اشتراکگذاری و جمع آوری اطلاعات خصوصی کاربران شدهاند.
البته کوکیهای ثالث، کاربردهای مفیدی هم دارند؛ مانند امکان پیاده سازی لاگین و اعتبارسنجی یکپارچهی بین چندین برنامه که به آن SSO یا Single Sign On هم گفته میشود؛ نمونهی آن، استفاده از Identity server و یا OpenId dict در دنیای داتنت است.
اما ... در کل به علت مشکلات یاد شده، اکثر مرورگرها تصمیم به عدم پذیرش و پردازش آنها گرفتهاند. برای مثال مرورگر Safari سالها است که اینگونه کوکیها را بلاک میکند و یا مرورگر فایرفاکس، کوکیهای ثالث ردیابها را بلاک میکند و ... مرورگر کروم نیز تصمیم گرفتهاست، تا پایان سال 2024، به این جمع محلق شود. هرچند اخیرا اعلام کردهاند، بجای اینکه مرورگر کروم، راسا این کار را انجام دهد، قرار است امکان انتخاب این گزینه به خود کاربر واگذار شود (چون ... خود گوگل از این نوع کوکیها منتفع است!). البته این تصمیم، بهنظر W3C خوش نیامده و اعلام کردهاند که این نوع کوکیها باید بروند!
روش آزمایش برنامهها برای بررسی تاثیر ممنوعیت کوکیهای ثالث
برای اینکه پیش از موعد، امکان آزمایش برنامهی خود را داشته باشید و بتوانید تاثیر ممنوعیت بکارگیری کوکیهای ثالث را بررسی کنید، در مرورگر کروم به آدرس زیر مراجعه کرده:
chrome://flags/#test-third-party-cookie-phaseout
و سپس این گزینه را فعال کنید و یا روش دوم فعالسازی آن، اجرای مرورگر کروم با سوئیچ test-third-party-cookie-phaseout-- از طریق خط فرمان است.
کدام برنامهها با ممنوعیت کوکیهای ثالث مشکل پیدا میکنند؟
اگر برنامهی SSO شما، مبتنی بر اعتبارسنجی یکپارچهی از نوع implicit flow است، حتما مشکل پیدا میکنید. در این حالت بهتر است به نوع امنتر authorization flow + PKCE مهاجرت کنید.
علت مسدود شدن نوع اعتبارسنجی و احراز هویت implicit flow که در برنامههای تک صفحهای وب (SPA/single-page apps) مرسوم است، شباهت بسیار زیاد آن به کاری است که ردیابهای اینترنتی انجام میدهند. در اینحالت، سایتهای ثالث، یک iframe مخفی را در پشت صحنه، درون سایت جاری باز کرده و توسط آن شروع به استفادهی از امکانات مرتبط با کوکیها میکنند. این الگو دقیقا همان کاری است که توسط implicit flow هم انجام میشود. بنابراین مرورگری که کوکیهای ثالث از این دست را مسدود میکند، قابلیت اعتبارسنجی یکپارچهی برنامههای SPA را هم غیرفعال خواهد کرد.
بازنویسی سطح دوم کش برای Entity framework 6
public IList<string> GetUserPermissions(int[] roleIds, int userId) { var permissionsOfRoles = (from p in _permissions from r in p.ApplicationRoles where roleIds.Contains(r.Id) select p.Name).Cacheable().Future(); var permissionsOfUser = (from p in _permissions from r in p.AssignedUsers where userId == r.Id select p.Name).Cacheable().Future().ToList(); return permissionsOfUser.Union(permissionsOfRoles).ToList(); }
The source query must be of type ObjectQuery or DbQuery. Parameter name: source
[ArgumentException: The source query must be of type ObjectQuery or DbQuery. Parameter name: source] EntityFramework.Extensions.FutureExtensions.Future(IQueryable`1 source) +249
تدارک یک آزمایش برای بررسی میزان افزایش کارآیی Reflection در دات نت 7
یک برنامهی کنسول جدید را ایجاد کرده و سپس کلاس Person را به صورت زیر به آن اضافه میکنیم:
namespace NET7Reflection; public class Person { private int _age; internal Person(int age) => _age = age; private int GetAge() => _age; private void SetAge(int age) => _age = age; }
به همین جهت ابتدا کتابخانهی BenchmarkDotNet را با TargetFramework دات نت 7 به صورت زیر به پروژه اضافه میکنیم:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net7.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> </PropertyGroup> <ItemGroup> <PackageReference Include="BenchmarkDotNet" Version="0.13.4" /> </ItemGroup> </Project>
using System.Reflection; using BenchmarkDotNet.Attributes; namespace NET7Reflection; [MemoryDiagnoser(false)] public class Benchmarks { private readonly object?[] _ageParams = { 30 }; private readonly ConstructorInfo _ctor = typeof(Person).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, new[] { typeof(int) })!; private readonly MethodInfo _getAgeMethod = typeof(Person).GetMethod("GetAge", BindingFlags.NonPublic | BindingFlags.Instance)!; private readonly Person _person = new(10); private readonly MethodInfo _setAgeMethod = typeof(Person).GetMethod("SetAge", BindingFlags.NonPublic | BindingFlags.Instance)!; [Benchmark] public int GetAge() => (int)typeof(Person).GetMethod("GetAge", BindingFlags.NonPublic | BindingFlags.Instance)! .Invoke(_person, Array.Empty<object?>())!; [Benchmark] public int GetAgeCachedMethod() => (int)_getAgeMethod.Invoke(_person, Array.Empty<object?>())!; [Benchmark] public void SetAge() => typeof(Person).GetMethod("SetAge", BindingFlags.NonPublic | BindingFlags.Instance)! .Invoke(_person, new object?[] { 30 }); [Benchmark] public void SetAgeCachedMethod() => _setAgeMethod.Invoke(_person, new object?[] { 30 }); [Benchmark] public void SetAgeCachedMethodCachedParams() => _setAgeMethod.Invoke(_person, _ageParams); [Benchmark] public Person Ctor() => (Person)typeof(Person).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, new[] { typeof(int) })! .Invoke(_person, new object?[] { 30 })!; [Benchmark] public Person CtorCachedCtorInfo() => (Person)_ctor.Invoke(_person, new object?[] { 30 })!; [Benchmark] public Person CtorCachedCtorInfoCachedParams() => (Person)_ctor.Invoke(_person, _ageParams)!; }
- در اینجا نحوهی کار با متدهای خصوصی کلاس Person را توسط Reflection مشاهده میکنید. برای مثال در متد GetAge، به نحو متداولی این کار صورت گرفتهاست. در متد GetAgeCachedMethod، قسمت دریافت اطلاعات متد، کش شدهاست و برای نمونه در متد SetAgeCachedMethodCachedParams، هم کش شدن قسمت دریافت اطلاعات متد را مشاهده میکنید و هم کش شدن پارامتر ارسالی به آنرا.
- این آزمایش را با فراخوانی زیر و تنظیم target framework به دات نت 6 و سپس دات نت 7، به صورت جداگانهای اجرا میکنیم:
using BenchmarkDotNet.Running; using NET7Reflection; BenchmarkRunner.Run<Benchmarks>();
و با target framework دات نت 7 به صورت زیر:
همانطور که مشاهده میکنید، در اکثر موارد، کارآیی Reflection در دات نت 7، حداقل 2 برابر نمونهی مشابه دات نت 6 است.
چه تغییری در دات نت 7 سبب بهبود قابل ملاحظهی کارآیی Reflection شدهاست؟
جزئیات تغییرات صورت گرفتهی در Reflection دات نت 7 را میتوانید در این pull request مشاهده کنید که در حقیقت از امکانات سطح پایین IL Emit استفاده کردهاند. در این مورد پیشتر تعدادی مطلب ذیل عنوان «آشنایی با Reflection.Emit» در این سایت منتشر شدهاند که میتوانید آنها را بررسی کنید.
در کل هرچند تغییرات جدید دات نت مانند ارائهی انواع و اقسام source generators، در تعدادی از موارد نیاز به Reflection را کمتر کردهاند و کارآیی بیشتری را ارائه دادهاند، اما Reflection هیچگاه منسوخ نخواهد شد و هرگونه بهبود کارآیی در این زمینه، بر روی کل فریمورک و برنامههای مشتق شدهی از آن، تاثیر قابل توجهی را خواهد گذاشت.
منابع مطالعاتی ASP.NET Core
ذخیره سریع دهها هزار رکورد دیتاتیبل در اکسل
http://npoi.codeplex.com/
نمونه: http://www.zachhunter.com/2010/05/getting-started-with-npoi/