Web Devs
641 subscribers
218 photos
22 videos
17 files
233 links
Articles, News, Jokes, Quotes, Back-End and UI/UX for web developers.
Github : https://github.com/fullStackDevsGroup
Advertising: @adsfullStackDevs
Download Telegram
#PersianDateTime
#CSharp
🔹 ساختار تاریخ شمسی با متد های تبدیل به تاریخ میلادی و یا هجری
🔸 متدهای مختلف برای بدست آوردن رشته های مختلف تاریخ شمسی با فرمت های متفاوت و اعداد فارسی
🔹 پشتیبانی از سال کبیسه
🔸 شبیه سازی کامل ساختار DateTime
.NetFramework 4.5

نصب پکیج :

Install-Package ABluePersianDateTime -Version 1.0.5
dotnet add package ABluePersianDateTime --version 1.0.5
paket add ABluePersianDateTime --version 1.0.5

@fullStackDevs
#EF_Core3
#FromSqlRaw
#ExecuteSqlRaw
🔹 بررسی تغییرجدیدی که از preview 4 بروی EF Core 3.0 اعمال شده است.
در نسخه های قبلی از این متد FromSql برای اجرای یک raw SQL query به صورت مستقیم استفاده میشد.
اما در نسخه جدید (3.0) از متد های

FromSqlRaw ، ExecuteSqlRaw ExecuteSqlRawAsync

برای اجرای یک raw SQL query که پارامتر های آن به صورت جدا در کوئری استرینگ مقدار دهی میشوند، استفاده میشوند.این متد ها جایگزین متد FromSql شده اند.

context.Products.FromSqlRaw(
"SELECT * FROM Products WHERE Name = {0}",
product.Name);

همچنین از متدهای

FromSqlInterpolated, ExecuteSqlInterpolated, ExecuteSqlInterpolatedAsync

برای اجرای یک raw SQL query استفاده میشوند با این تفاوت که در این متدها پارامتر های کوئری در مابین کوئری استرینگ و نه به صورت جدا مقداردهی میشوند.

context.Products.FromSqlInterpolated(
$"SELECT * FROM Products WHERE
Name = {product.Name}"
);

تغییر دیگری که در نسخه جدید اتفاق افتاده است محل صدا زدن این متد هاست. در نسخه های قبل تر از (3.0 )متد FromSql را در هر جای کوئری لینک خود میتوانستید صدا بزنید اما از در نسخه جدید متد های جایگزین شده را فقط مستقیما بروی DbSet<> می توانید صدا بزنید.
هدف از انجام این تغییر هم فقط برای جلوگیری از ابهام در کوئری، آن هم در سناریوهای خاص بوده است.

@fullStackDevs
در EF و همچنین Ef Core برای انجام Configuration هایی بروی Entity کلاس ها از Fluent API Configuration استفاده میکنیم و بایستی این Configuration ها را به ModelBuilder معرفی کنید. عموما میبینیم که برای انجام اینکار ، Extension Method ای مینویسند و با Reflection این کار را انجام میدهند اما خود Ef و Ef core متدی برای انجام اینکار دارد و اصلا نیازی به نوشتن Extension Method نیست .
این متد به عنوان پارامتر ورودی،اسمبلی ای که Configuration های شما در آن قرار دهد را دریافت میکند , پارامتر بعدی که میتوانید به این متد پاس دهید predicate ای برای اعمال Limitation هایی میباشد .با این متد میتوانید تمامیه Configuration هایی که باید به ModelBuilder افزوده شوند را Apply کنید.
#Value_Conversions
#EFCore

🧩 Value Conversions

این ویژگی در EF Core 2.1 اضافه شد.
ویژگی Value Conversion امکان تبدیل مقادیر پراپرتی ها به تایپ های مشخص در هنگام خواندن یا نوشتن در دیتابیس را میدهد.
این تبدیل میتواند از یک نوع به همان نوع یا از یک نوع به نوع دیگر باشد مانند تبدیل مقادیر enum به string و برعکس.
برای مثال برای ذخیره مقادیر enum بصورت string به شکل زیر میتوانیم عمل کنیم :

public class Rider
{
public int Id { get; set; }
public EquineBeast Mount { get; set; }
}

public enum EquineBeast
{
Donkey,
Mule,
Horse,
Unicorn
}
و سپس برای اینکه مقادیر این enum در دیتابیس به صورت string ذخیره شود ، به این صورت "Donkey", "Mule" بایستی Value Conversion ای بدین شکل تعریف کنیم .
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder
.Entity<Rider>()
.Property(e => e.Mount)
.HasConversion(
v => v.ToString(),
v => (EquineBeast)Enum.Parse(typeof(EquineBeast), v));
}

یا به عنوان مثال حتما تا کنون برای شما پیش آمده که در درون Entity Class خود برای یک پراپرتی از Complex type استفاده کرده باشد.
مثلا برای نگه داری مقدار پول به جای استفاده از type های decimal یا int ، از یک custom type که خود انرا تعریف کرده اید استفاده کرده باشید.

public class MyEntity
{
...
public Money salary { get; set; }
//Money is a class, actually it's my custom type
}
برای ذخیره چنین type هایی در دیتابیس و واکشی انها در قالب custom type مان، میتوانیم از ویژگی Value conversion کمک بگریم.
برای انجام اینکار بایستی برای پراپرتی salary (در مثال بالا) یک ValueConverter در متد OnModelCreating در Context بسازیم اینکار به دو صورت قابل انجام است .
روش اول
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<MyEntity>()
.Property(b => b.Salary )
.HasConversion(
v => JsonConvert.SerializeObject(v),
v => JsonConvert.DeserializeObject<Money>(v));
}
و روش دوم
var converter = new ValueConverter<Money, string>(
v => JsonConvert.SerializeObject(v),
v => JsonConvert.DeserializeObject<Money>(v));

modelBuilder
.Entity<MyEntity>()
.Property(e => e.Salary)
.HasConversion(converter);

✔️ توجه داشته باشد که برای ذخیره شی Money در دیتابیس و واکشی آن از دیتابیس در قالب یک Money روال سریالایز و دیسریالایز کردن آن به Json نیازمند است.

روش دوم برای مواردی که دو پراپرتی از یک value converter استفاده میکنند مناسب است.
*نکته مقادیر null به value converter پاس داده نمیشوند.
خود Ef Core نیز کلاس های value converter از پیش تعریف شده ای دارد که در فضای نام
Microsoft.EntityFrameworkCore.Storage.ValueConversion
وجود دارند .که لیستی ار آنها را در این لینک میتوانید ببینید.به همین خاطر EF Core با دارا بودن لیستی از این value converter بسیاری از تبدیلات نوع ها به نوع های دیگر در هنگام ذخیره مقادیر در دیتابیس را به صورت اتوماتیک انجام میدهد در واقع این امر زمانی مشخص میشود که DataBase Provider خود را مشخص و کانفیگ میکنید.
مثلا مثال enum بالا را میتوانید با value converter های خود ef core انجام دهید.

var converter = new EnumToStringConverter<EquineBeast>();

modelBuilder
.Entity<Rider>()
.Property(e => e.Mount)
.HasConversion(converter);

🎯 و نکته اخر اینکه
با مشخص کردن نوع یک پراپرتی به صورت صریح به کمک اتریبیوت
 [Column(TypeName = "TypeName")]
می توان همین کار را انجام داد و Ef Core متوجه میشود که باید مقدار این پراپرتی رو در هنگام ذخیره در دیتابیس به نوع مورد نظر تبدیل کند.
این ویژگی هنوز محدودیت هایی دارد برای مثال :
-مقادیر null نمیتوانند تبدیل شوند
-امکان اعمال یک value converter به صورت کلی برای دسته ای از پراپرتی ها نیست و باید به صورت تک به تک اعمال شوند.
-استفاده از value conversions ممکن است توانایی EF Core را برای ترجمه عبارات به SQL تحت تأثیر قرار دهد.


@fullStackDevs
#High_Performance
#EfCore_Best_Practice
#DbContext_pooling

🔸 در این پست به معرفی یک روش جدید Register کردن DbContext به Di Container در متد ConfigureServices در کلاس Startup می پردازیم.
ابتدایی ترین و ساده ترین روش که برای Register کردن custom DbContext خود به سیستم dependency injection استفاده میکنیم تا بعدا نمونه ای از custom DbContext خود به صورت constructor parameters و یا دیگر روش های دریافت Instance از DI، دریافت کنیم روش زیر است :
services.AddDbContext<
BloggingContext
>(options => options.UseSqlServer("ConnectionString"));

🔹 که Register کردن DbContext به این طریق به معنی ساختن یک instance جدید از DbContext برای هر Request میباشد که مطمئنا روال Instance سازی از DbContext هزینه هایی برای اپلیکیشن دارد.
در نسخه 2.0 از Ef Core روش جدید برای Register کردن DbContext به سیستم dependency injection معرفی شد که همانطور که در مثال بعدی خواهید به صورت شفاف مجموعه ای از موارد DbContext قابل استفاده مجدد را ارائه می دهد.

services.AddDbContextPool<BloggingContext>(
options => options.UseSqlServer(
ConnectionString
));

▪️ اگر از این متد برای Register کردن DbContext استفاده کنید زمانیه که در اپلیکیشن درخواست نمونه ای جدید از DbContext داده شود ابتدا در Context Pool چک میشود که ایا نمونه ای از DbContext وجود دارد و اگر نمونه ای وجو داشت،در اختیار درخواست دهنده قرار میدهد.
در نهایت هنگامی که Request پردازش شد و کار ان با نمونه دریافت شده DbContext تمام شد، Ef تمامیه State های قابل ردیابی DbContext را که از آنها آگاه هست را reset کرده و DbContext inctance دوباره به Context Pool بر میگردد.
این روال از نظر مفهومی شبیه connection pooling در Ado.net است و از مزیت های آن میتوان به کاهش هزینه ساخت DbContext instance اشاره کرد.
استفاده از این متد البته باعث محدودیت های اندکی در متد OnConfiguring() در DbContext میشود.

🔻 نکته بسیار مهم

نکته مهم این است که اگر به صورت Custom مکانیزمی را در derived DbContext class خود پیاده کرده باشید که باعث نگه داری state ای شود و از انجایی که Ef core فقط state هایی که از آنها اگاه هست را reset میکند پس در نتیجه state که شما به صورت custom ایجاد کرده اید در DbContext instance باقی میماند و باعث share شدن آن در بین درخواست ها میشود.


@fullStackDevs
#Scrutor

Assembly scanning and decoration extensions for Microsoft.Extensions.DependencyInjection
Scrutor is not a dependency injection (DI) container itself, instead it adds additional capabilities to the built-in container.
The library itself is pretty simple; it provides a single extension method, Scan, along with a fluent API to IServiceCollection that allows you to register "services" based on conventions. That's it!

Useful for lazy Developers😉

Package Manager Console

Install-Package Scrutor

.NET Core CLI

dotnet add package Scrutor

by Kristian Hellang

MoreDetail
Documentation
GitHub

@fullStackDevs
Web Devs
#PersianDateTime #CSharp 🔹 ساختار تاریخ شمسی با متد های تبدیل به تاریخ میلادی و یا هجری 🔸 متدهای مختلف برای بدست آوردن رشته های مختلف تاریخ شمسی با فرمت های متفاوت و اعداد فارسی 🔹 پشتیبانی از سال کبیسه 🔸 شبیه سازی کامل ساختار DateTime .NetFramework 4.5 نصب…
#PersianDateTime
#CSharp
🔹 ساختار تاریخ شمسی با متد های تبدیل به تاریخ میلادی و یا هجری


✔️ اضافه کردن اپراتور منها برای بدست آوردن تفاضل دو تاریخ
مثال:
  PersianDateTime datetime1 = new PersianDateTime(_dateTime);
PersianDateTime datetime2 = new PersianDateTime(_dateTime.AddDays(-10));
var timeSpan = datetime1 - datetime2;

.NetFramework 4.5

🔳 در پست بعدی تو این هفته compatible با NetCore هم توی ناگت برای استفاده قرار داده میشود.

نصب پکیج :

Install-Package ABluePersianDateTime -Version 1.0.7
dotnet add package ABluePersianDateTime --version 1.0.7
paket add ABluePersianDateTime --version 1.0.7


@fullStackDevs
#Kotlin
#FreeCourse
#DevelopingAndroidApps

دوره رایگان برنامه نویسی اندروید با زبان برنامه نویسی Kotlin منتشر شده توسط شرکت گوگل

https://www.udacity.com/course/developing-android-apps-with-kotlin--ud9012


https://t.me/fullStackDevs
#stackblitz

✔️در مرورگر شما
فقط با یک کلیک برنامه را کامل ایجاد ، ویرایش و استقرار کنید.

یه سایت خوب و کاربردی برای اینکه بتونید انلاین کدی رو چک کنید یا بتونید یه اپلیکیشنی به صورت سمپل درست کنید.
در واقع یه VS Code انلاین هستش که میتونید اپ های زیر را توسعه بدید:
🔹Angular
🔸React
🔹Ionic
🔸TypeScript
🔹RxJS
🔸Svelte

لینک سایت :
StackBlitz

@fullStackDevs
#Boxing
#UnBoxing

🧩 Boxing & unBoxing in C#

زبان برنامه نویسی سی شارپ دارای یک سیستم واحد نوع داده ای است. یعنی تمام دیتا تایپ ها در این زبان به صورت مستقیم یا غیر مستقیم از کلاس object ارث بری میکنندکه شامل value type ها و هم reference type ها میشود.
همانطور که میدانید متغیر های value type مستقیما دربردرانده دیتای خود هستند و دیتای آنها در حافظه stack ذخیره میشود. اما متغیر های reference type که به انها ابجکت گفته میشود، فقط reference ای از دیتای خود دارند و دیتای آن ها در حافظه managed heap ذخیره میشود.

زمانی که یک متغیر valute type را به یک متغیر reference type(آبجکت) اختصاص میدهید(assign) عمل Boxing اتفاق می افتد.
مثال :
int i = 24;
object ob = i;
یا
object ob1=21; 

در هر دو مثال بالا عمل Boxing اتفاق می افتد.
متغیر i که ار نوع integer است دارای مقدار 24 میباشد که در حافظه stack ذخیره شده است و در خط بعد این متغیر به یک object کپی شده است. یعنی آبجکت ob هم اکنون به یک مقدار integer اشاره میکند و هر دو متغیر شامل عدد 24 و به صورت مستقل از هم هستند و تغییر در یکی بر روی دیگری اثری نمیگذارد.
عمل Boxing در سی شارپ حافظه و زمان زیادی را مصرف میکند بدلیل اینکه به آبجکتی که به یک value type اشاره میکند باید مقدار حافظه ای در heap اختصاص داده شود و در مرحله بعد یک کپی از مقدار متغیر value type که در حافظه stack میباشد به حافظه ی heap اختصاص داده شده آن آبجکت، منتقل شود.

عمل unBoxing برعکس Boxing میباشد یعنی زمانی که یک متغیر از نو reference type (آبجکت) را سعی میکنید به یک متغیر از نوع value type تبدیل کنید.
در unBoxing مقدار متغیر reference type از حافظه heap به محل اختصاص داده شده متغیر value type در حافظه stack منتقل میشود . برخلاف عمل Boxing در unBoxing بایستی به صورت صریح این عمل casting را ذکر کنید.مثال :
int i = 24;
object ob = i; //Boxing
int j = (int) ob;//unBoxing

مقدرا اختصاص داده شده به متغییر ob از نوع integer باید دوباره به همان نوع (integer) به صورت صریح cast شود.
در واقع عملیات Boxing به صورت implicit و عملیات unBoxing به صورت explicit انجام میشود.
عملیات unBoxing نیز همانند Boxing حافظه و زمان زیادی مصرف میکند.

@fullStackDevs
🌀 Specification pattern: C# implementation

در این پست به معرفی الگوی Specification میپردازیم و یک مثال فوق العده کاربردی ارائه میدهیم که یک گام معماری و کدتان به Domain Driven Design و Clean Code نزدیکتر میکند.
*توضیحات تکمیلی : این پست را بهتر است با تلگرام دسکتاب و در سایز maximize مطالعه فرمایید.

🔸 یکی مزایای استفاده از این الگو را میتواند Encapsulation کردن اطلاعاتی که در مورد Domain میباشد دریک قسمت واحد بشمار آورد.
موارد استفاده از این الگو با ذکر یک مثال به طور کامل بیان شده است.

فرض کنید یکی از کلاس های دامین مدل ما کلاس Movie باشد که به صورت زیر تعریف شده است :

public class Movie : Entity
{
public string Name { get; }
public DateTime ReleaseDate{get;}
public MpaaRating MpaaRating {get;}
public string Genre { get; }
public double Rating { get; }
}

public enum MpaaRating
{
G,
PG13,
R
}
🔹 حالا فرض کنیم که کاربر فیلم های تازه ساخته شده را میخواهد تماشا کند. برای نمایش این فیلم ها به کاربر معمولا در Repository مربوطه متدی به شکل زیر تعریف میکنیم :

public class MovieRepository
{
public IReadOnlyList<Movie> GetByReleaseDate(DateTime minReleaseDate)
{
/* ... */
}
}
یا اگر به فیلم هایی براساس Rate یا Genre یا دیگر شاخص ها نیاز داشته باشیم بدین شکل معمولا متد های ریپازیتوری مان را تعریف میکنیم :
public class MovieRepository
{
public IReadOnlyList<Movie> GetByReleaseDate(DateTime maxReleaseDate) { }

public IReadOnlyList<Movie> GetByRating(double minRating) { }

public IReadOnlyList<Movie> GetByGenre(string genre) { }
}
🔸 ریپازیتوری قدری پیچیده میشود اگر پارامترهای جست و جوی ما پیچیده تر شوند مثلا اگر تمامیه فیلم هایی را که در تاریخ انتشار مشخص و با ژانر خاصی هستند نیاز داشته باشید معمولا دوباره به ازای آن یک متد در ریپازیتوری مربوطه تعریف میکنید.
برای نوشتن این متد روش های زیادی وجود دارد مانند اکستنشن متد،یا یک متدی که به صورت جداگانه این فیلتر ها را بروی Dbset<Movie> اعمال کند. اما این راه حل ها راهای درستی نیستند و از جمله معیاب آن میتوان به نقض کردن اصل DRY میباشد چون بایستی به ازای هر Dbset این متد ها را که حتی ممکن است logic های یکسانی داشته باشند ، تکرار کنید.
اکنون شاید با خود میگویید خب میتوانیم از یک متد Generic برای جلوگیری از این تکرار استفاده کنیم .
راه حل این مشکل استفاده از الگوی specification است . اما با یک پیاده سازی خاص .در این پست دو پیاده سازی از این الگو ارائه خواهییم داد.
پیاده سازی اول یک پیاده سازی ساده با عنوان Naive implementation است.و در ادامه به سمت بهتر کردن ان پیش میرویم.
اولین راه حل برای مقابله با مشکل بالا (ایجاد متد های متعدد برای شاخص های متعدد در جست و جو و مرتب سازی و..) استفاده از امکان expressions در سی شارپ است تا حدی زیادی آنها خودشان هم یک پیاده سازی از الگوی specification هستند. پس میتوانید یک متد در ریپازیتوری خود بنویسیدکه به عنوان پارامتر یک expression ورودی بگیرد مثال :
// Controller
public void SomeMethod()
{
Expression<Func<Movie, bool>> expression = m => m.MpaaRating == MpaaRating.G;
var movies = _repository.Find(expression); // Getting a list of movies
}
// Repository
public IReadOnlyList<Movie> Find(Expression<Func<Movie, bool>> expression)
{
return db
.Where(expression)
.ToList();
}
مشکلی که با این روش وجود دارد این است که با اینکه شروط مربوط به دامین مدل مان را در یک مکان واحد جمع اوری کردیم (در متغیر Expression) اما چنین متغیر هایی در این سطح (Controller) برای چنین اطلاعات مهمی اصلا مناسب نیستند.در این روش امکان دوباره استفاده از این شروط بسیار سخت میشود و حتی تمایل به duplicate در کل اپلیکیشن بشدت افزایش پیدا میکتد.و متاسفانه دوباره در نهایت به مشکل اول باز میگردیم.
حال نوبت به یک پیاده سازیه ساده از الگوی Specification تحت عنوان GenericSpecification میرسد.
public class GenericSpecification<T>
{
public Expression<Func<T , bool>> Expression { get; }

public GenericSpecification(Expression<Func<T , bool>> expression)
{
Expression = expression;
}
public bool IsSatisfiedBy(T entity)
{
return Expression.Compile().Invoke(entity);
}
}
نحوه استفاده از آن در پست بعدی ...

@fullStackDevs
ادامه پست قبل :
🌀 Specification pattern

نحوه استفاده از آن


// Controller
public void SomeMethod()
{
var specification = new GenericSpecification<Movie>(
m => m.MpaaRating == MpaaRating.G);
var movies = _repository.Find(specification); // Getting a list of movies
}

// Repository
public IReadOnlyList<Movie> Find(GenericSpecification<Movie> specification)
{
return db
.Where(specification.Expression)
.ToList();
}
🔹 اما در این روش هم باز همان مشکل قبل را داریم و کلاس جنریک specification در اینجا فقط به عنوان یک wrapper برروی expression قبلی مان عمل میکند پس نتیجه ای که میتوانیم بگیریم این است که GenericSpecification یک روش بد میباشد.چون فقط نقش یک Container را ایفا میکند که Client ها به اطلاعات خود را پاس میدهند و مشکل کپسوله سازی اطلاعات دامین مدل ها هنوز پا برجا و حل نشده باقی مانده است.

✔️ اما راهکار چیست؟

🔳 راه حل درست، استفاده از پیاده سازی ای از الگو specification تحت عنوان Strongly-typed specifications میباشد.
در این روش الگوی specification طوری پیاده سازی شده است که در آن اطلاعات دامین مدل نوشته شده و با کمترین امکان تغییر از خارج از کلاس پیاده سازی کننده پیاده سازی شده است. نحوه پیاده سازی :
public abstract class Specification<T>
{
public abstract Expression<Func<T , bool>> ToExpression();

public bool IsSatisfiedBy(T entity)
{
Func<T , bool> predicate = ToExpression().Compile();
return predicate(entity);
}
}
public class MpaaRatingAtMostSpecification : Specification<Movie>
{
private readonly MpaaRating_rating;

public MpaaRatingAtMostSpecification(MpaaRating rating)
{
_rating = rating;
}
public override Expression<Func<Movie, bool>> ToExpression()
{
return movie => movie.MpaaRating <= _rating;
}
}
// Controller
public void SomeMethod()
{
var gRating = new MpaaRatingAtMostSpecification(MpaaRating.G);
IReadOnlyList<Movie> movies = repository.Find(gRating); // Getting a list of movies
}
// Repository
public IReadOnlyList<T> Find(Specification<T> specification)
{

return db.Where(specification.ToExpression()).ToList();
}
}
🔸 در این روش باید به ازای هر شاخص یا عملگری که میخواهید به عنوان یک فیلتر بر روی DbSet انجام شود،باید کلاسی تعریف کنید که از ابستراکت کلاس Specification<T> ارث بری کرده و متد ToExpression() انرا override و پیاده سازی کند. مثلا در مثال بالا ما به ازای شاخص MpaaRating که یک enum در کلاس Movie بود .یک کلاس با نام MpaaRatingAtMostSpecification ایجاد کردیم که از ابستراکت کلاس Specification<T> ارث بری کرده و با override کردن ToExpression() و پیاده سازی آن به صورت :
public override Expression<Func<Movie, bool>> ToExpression()
{
return movie => movie.MpaaRating <= _rating;
}
شرط خود را نوشته و در سطح کنترلر اگر نیاز به فیلتر Movie ها بر اساس شاخص MpaaRating داشتیم با نمونه سازی از این کلاس به صورت :
var gRating = new MpaaRatingAtMostSpecification(MpaaRating.G);
IReadOnlyList<Movie> movies = repository.Find(gRating); // Getting a list of movies
و پاس دادن آن به متد Find ریپازیتوری خودمان :
// Repository
public IReadOnlyList<T> Find(Specification<T> specification)
{
return db.Where(specification.ToExpression())
.ToList();
}
آنرا بر روی Dbset<Movie> اعمال کنیم.پس اگر قرار باشد فیلتری براساس شاخص یا عملگر دیگری اعمال کنید باید یک کلاس جدیدبسازید که از ابستراکت کلاس Specification<T> ارث بری میکند و با پیاده سازی متد ToExpression() شرط مورد نظر خود بنویسید.


لینک مطلب


@fullStackDevs
#OAuth

🌀OAuth authorization

🔹 در این پست می آموزیم که OAuth چیست.
درابتدا باید بدانیم که OAuth مخفف Open Authorization میباشد.
OAuth
🔸 یک پروتکل برای اهدای مجوز برای دسترسی به اطلاعات کاربر توسط اپلیکیشنی دیگر است.
این پروتکل ابتدا در سال 2007 معرفی شد و توسط توییتر استفاده شد و با توجه به استقبال و گستردگی ان در سال 2010 نسخه OAuth 2.0 توسط IEFT (جامعه بین المللی آزاد از طراحان شبکه ، اپراتورها ، فروشندگان و محققانی است که بر روی تدوین استانداردهای فنی برای اینترنت کار می کنند.) معرفی شد.

🔻 برای مثال ممکن است موقع ثبت نام در سایتی گزینه هایی همچون “login with Google” یا “login with Facebook” را دیده باشید که عملیات login را بسیار ساده میکند و با اعطای مجوز دسترسی به اطلاعاتتان به سایتی که میخواهید در آن حساب بسازید عملیات ورود و ساخت حساب را انجام میدهید.

✔️ سه اجزایی که در یک مکانیزم OAuth وجود دارند عبارتند از :
1️⃣ OAuth Provider , Resource Provider

سرویسی که با دریافت تاییدیه امکان استفاده از اطلاعات کاربر را به یک اپلیکیشن دیگر میدهد. مانند گوگل ، فیس بوک و... که بایستی پروتکل OAuth ار پیاده سازی کرده باشد.

2️⃣ OAuth Client

وب سایت یا اپلیکیشنی که اجزای دسترسی به اطلاعاتمان را به آن میدهیم.

3️⃣ Resource Owner

شخصی که اطلاعات آن در اختیار Resource Provider است.
طی این فرایند شما با اعطای مجوز به OAuth Client و دریافت یک access token این امکان را به OAuth Client میدهید که به اطلاعات شما از طریق آن access token دسترسی داشته باشد .

@fullStackDevs
#SVG
#ScalableVectorGraphics

🔻 این SVG چیست و چرا باید از آن استفاده کنیم؟

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


ما به عنوان طراح سایت میخواهیم که تصاویری داشته باشیم که به هر اندازه که بخواهیم بزرگشان کنیم و کیفیتشان از بین نرود که با SVG امکان پذیراست اما قبل تر با وجود مرورگرهای قدیمی ما را از استفاده از چنین قابلیتی دور نگه می داشت. اما خوشبختانه امروزه می توان از این قابلیت بهره برد.

این بدین معنی نیست که در آینده نزدیک از تصاویری با فرمت های PNG، JPG و غیره دیگر استفاده نمی شود، نه، بلکه آنها همچنان کاربرد خود را در وب خواهند داشت و در کنار SVG به حیات خود در دنیای وب ادامه خواهند داد.

🔻 حالا SVG چیست؟
SVG (Scalable Vector Graphics)

در دنیای کامپیوتر ترسیمات می توانند از دو نوع Raster یا Vector باشند.

در Raster Graphics یا گرافیک شطرنجی تصویر به صورت مجموعه ‌ای از پیکسل‌ها ذخیره می‌شود و رنگ هر پیکسل به طور جداگانه ذخیره می‌شود. تغییر اندازه این تصاویر کیفیت آنها را تحث تاثیر قرار می دهد. اکثر فرمت‌های رایج فایل‌های تصویری مانند jpg، gif، و bmp بر مبنای گرافیک شطرنجی هستند.

در Vector Graphics یا گرافیک برداری روشی در تولید و ذخیرهٔ فایل‌های تصویری کامپیوتری است که در آن تصویر در قالب مجموعه‌ای از مشخصات هندسی نقاط، خط‌ها، منحنی‌ها و چندضلعی‌ها ذخیره می‌شود. واژهٔ «بردار» در این کاربرد معنایی وسیع‌تر از یک خط راست دارد.

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

این تصاویر مستقل از رزولوشن هستند و می‌توان آنها را بزرگ و کوچک کرد و در هر رزولوشن بدون از دست دادن جزئیات و وضوح چاپ کرد. یکی از شناخته شده ترین فرمت‌های ذخیرهٔ فایل‌های گرافیک برداری، فرمت SVG است.

در SVG بر اساس XML است این یعنی سینتکس آن خیلی هم غریبه نخواهد بود و به HTML شباهت دارد. به این صورت که برای ترسیم شکل های مختلف تگ های مختلف وجود دارد مثلا برای ترسیم دایره از تگ
<circle/>
استفاده می شود و در نهایت همه اشکال، درون یک تگ
<svg />
قرار می گیرند.
ادامه در پست بعدی ...
@fullStackDevs
ادامه پست قبل

🔻 چرا SVG ؟

🔹 مستقل از رزولوشن

یکی از نقاط قوت SVG این است که در صفحه نمایش هایی با کیفیت بسیار بالا هم به بهترین شکل نمایش داده می شود و کیفیتش تغییر نمی کند. برخلاف تصاویر Raster که کیفیت خود را از دست می دهند و مجبوریم برای صفحه نمایش هایی با کیفیت بالاتر نسخه با کیفیت تری از تصویر را نمایش دهیم.

دیگر مهم نیست اندازه تصویر چه باشد، یا چقدر کاربر Zoom کند و یا اینکه کیفیت صفحه نمایش کاربر چه اندازه باشد. در همه این موارد SVG قصه ما همان حالت با کیفیت و تیزش را حفظ می کند.

🔸 سازگار با CSS

از اونجایی که SVG هم مثل HTML یک markup است می تواند Class یا css داشته باشد و از آن طریق در css می تواند در دسترس باشد.
پس می توانیم روی ترسیمات برداری از طریق css کارهای زیادی انجام دهیم که این کار برای ترسیمات Raster امکان پذیر نمی باشد.
فرض کنید مستطیلی را از طریق SVG ساخته ایم می توانیم رنگ آن را بصورت های مختلف تغییر دهیم ولی اگر همان مستطیل از نوع تصاویر معمولی مثلا با فرمت PNG بود می توان گفت دیگر این امکان برای ما وجود نداشت.

🔹 تعامل پذیری ساده از طریق Javascript

به همان دلیلی که SVG با CSS سازگار است می توان گفت که به راحتی می توان از طریق جاواسکریپت با آن تعامل داشت و مواردی مثل انیمیشن و غیره را به راحتی پیاده و در نتیجه تجربه کاربری و تعاملی خوبی را به سادگی برای کاربر مهیا کرد.

🔸 درخواست HTTP کمتر

هر زمان که بواسطه تگ <img> از تصویری به صورت عادی در یک صفحه وب استفاده کنید مرورگر برای ترسیم آن تصویر یک درخواست HTTP به سرور می فرستد تا تصویر را از سرور گرفته و نمایش دهد. اگر از روش خطی برای SVG استفاده کنیم SVG بصورت مستقیم در فایل HTML قرار دارد و دیگر نیازی به یک درخواست جداگانه برای تصویر ما نخواهد بود.

🔹 ویرایش ساده

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

🔸 حجم فایل کمتر

ترسیمات وکتور معمولا حجم کمتری را می گیرند مخصوصا اگر شکل و طرح ساده ای داشته باشند. پس فایل تصویر ما سایز کمتری خواهد داشت. همچنین فشرده سازی بصورت بهتری روی SVG اعمال می شود. پس می توان از نظر سایز صفحه وب هم با استفاده از SVG صرفه جویی داشته باشیم که از نظر کارایی کمک بسیار خوبی برای سایت ما خواهد بود.

🔹طراحی واکنشگرا

اگر تصویر شما می تواند بصورت SVG باشد دیگر نگرانی برای واکنشگرا بودن آن نخواهید داشت. ولی در صورت استفاده از تصاویری با فرمت PNG یا JPG شاید مجبور شوید تا در صفحه نمایش های مختلف نسخه های مختلفی از آن تصاویر را قرار دهید.

✔️ بهترین موارد استفاده SVG :

▪️ آیکون ها
▫️ ترسیمات ساده مثل شکل های مختلف
▪️ بنرهای تبلیغاتی
▫️ ترسیمات متحرک
▪️ اینفوگراف ها و مصورسازی داده ها
می باشند.

🌀 واضح است که اگر تصویری از یک منظره داشته باشیم که توسط یک عکاس گرفته شده است، نمایش آن بوسیله SVG منطقی نخواهد بود چرا که در این مورد حجم فایل به مراتب بیشتر از فرمت PNG یا JPG خواهد بود.

@fullStackDevs
Forwarded from Web Devs
#DesignPatterns

در مهندسی نرم افزار الگو های طراحی یک راه حل عمومیه تکرار پذیر برای حل یک مشکل رایج در هنگام طراحی نرم افزار می باشد.
به عبارتی الگو های طراحی یک راه کار نهایی که به طور مستقیم میتوان انرا به کد تبدیل کرد نیست بلکه توضیح یا قالبی است برای اینکه ، چطور میتوان مشکلی که به راه های متفاوت پدیدار میشود را حل کرد.
الگو های طراحی روند سرعت توسعه نرم افزار را با ارائه روش های تست شده افزایش میدهند.
یک طراحی موثر و تاثیر گذاری نیازمند مسائلی است که ممکن است تا زمان پیاده سازی قابل رویت نباشد .
استفاده از الگوهای طراحی باعث جلوگیری از مسائل جرئی که بروز مشکلاتی بزرگ را دربر دارد، میشوند.
استفاده از الگوهای طراحی باعث میشود که کد شما قابل انعطاف تر و نگهداری آن آسان تر و همچنین راحتر بتوان دوباره از ان استفاده کرد و هیچ لزومی ندارد که همیشه این الگوهای طراحی را در پروژه های خود استفاده کنید ،الگوهای طراحی برای توسعه پروژه منظور نمی شوند بلکه برای حل مسائل متداول در نظر گرفته شده اند.هر وقت که به آنها نیاز داشتید بایستی الگوی مناسبی برای جلوگیری از بروز چنین مشکلی در آینده پیاده سازی کنید برای تشخیص اینکه برای چه مشکلی از چه الگویی استفاده کنید فقط باید سعی کنید که الگو های طراحی و مهم تر از ان هدف از هر الگو را درک کنید
الگوهای طراحی براساس هدف هر الگو به سه دسته تقسیم میشوند.
🔹Behavioural
🔸Creational
🔹Structural

1️⃣ Creational
این نوع الگو ها در مورد نحوه نمونه سازی از کلاس ها میباشند و انها را میتوان به class-creation و object-creational دسته بندی کرد.این به این معنی است که در زمان انجام Job و پیاده سازی الگو برای دسترسی به ویژگی های یک کلاس یا میتوان از طریق ارث بری از ویژگی های ان استفاده کرد یا اینکه با ساخت یک نمونه از کلاس هدف به ویژگی های ان نیز دسترسی داشت.
الگو های Creational عبارتند از :
Factory Method, Abstract Factory, Builder, Singleton, Object Pool, Prototype

2️⃣ Structural
این نوع از الگوها مربوط به سازماندهی کلاس ها و اشیاء مختلف برای تشکیل ساختارهای بزرگتر و ارائه قابلیت های جدید است.
الگو های Structural عبارتند از :
Adapter, Bridge, Composite, Decorator, Facade, Flyweight, Private Class Data, Proxy

3️⃣ Behavioral
این نوع از الگو ها در مورد شناسایی الگوهای ارتباطی مشترک بین اشیاء و تحقق این الگوهاست دروافع الگوهای رفتاری آن الگوهایی هستند که به طور خاص به ارتباط بین اشیاء مربوط می شوند.
الگو های Behavioral عبارتند از :
Command, Interpreter, Iterator, Mediator, Memento, Null Object, Observer, State, Strategy, Template method, Visitor

در ادامه نیز به بررسی این الگو ها میپردازیم.

💎 Acting out rather than speaking out became a pattern 💎


@fullStackDevs
#Amaizing_DI_Libraries
#SimpleInjector

💫 SimpleInjector

یک DI Container بسیار ساده و قابل انعطاف که هدف آن سوق دادن توسعه دهنگان به سمت گود موفقیت میباشد.

پلترفرم هایی که توسط این لایبری ساپورت میشود :

▪️.NET 4.0 and up.
▪️ .NET Standard including:
▫️ Universal Windows Programs.
▫️ Mono.
▫️.NET Core.
▫️Xamarin.

🔸Simple Injector Integration libraries for AspNetCore
🔹SimpleInjector.Integration.AspNetCore

🔹SimpleInjector.Integration.AspNetCore.Mvc.Core

🔹SimpleInjector.Integration.AspNetCore.Mvc
All of the above available on nuget now

Simple injector nuget packages
Simple Injector on github
Simple Injector website & doc

📣 @fullStackDevs