اشتراک‌ها
ReSharper Ultimate 2018.3.1 منتشر شد

This bug-fix update resolves the following issues:

ReSharper Build couldn’t build a project if MSBuild was installed as part of Visual Studio 2019 Preview 1 (RSRP-472694).
Visual Studio froze on JavaScript debugging (RSRP-472802).
Inconsistent default state around ‘Inconsistent Naming‘ inspection (RSRP-472812).
A false positive for NUnit TestCase (RSRP-472787).
Unit test coverage highlighting is not shown for projects targeting .NET Framework 3.5 and lower (DCVR-9525).
False “Cannot convert type” error for Promise in TypeScript.
Find Usages did not process bodies of #define macros when looking for textual occurrences (RSCPP-24977).
“Remove unused parameter” quick-fix was broken in C++ (RSCPP-25094).
 

ReSharper Ultimate 2018.3.1 منتشر شد
اشتراک‌ها
دوره پیاده سازی معماری تمیز در ASP.NET Core

ASP.NET Core - Clean Architecture - Full Course
In this video, we'll be talking about ASP.NET Core - Clean Architecture. We'll cover the concept of clean architecture, how it helps with scaling and maintainability, works with the MVC pattern, and uses Fluent Validation.
 

دوره پیاده سازی معماری تمیز در ASP.NET Core
مطالب
فرم‌های مبتنی بر قالب‌ها در Angular - قسمت دوم - ایجاد اولین فرم
در قسمت قبل، مروری داشتیم بر تفاوت‌های دو نوع مختلف فناوری‌های ایجاد و مدیریت فرم‌ها در Angular و هچنین ساختار ابتدایی برنامه‌ی این سری را ایجاد کردیم. در ادامه، اولین فرم مبتنی بر قالب‌ها را ایجاد خواهیم کرد.


ایجاد اولین فرم مبتنی بر قالب‌ها

پس از ایجاد کامپوننت employee-register، فایل قالب آن یا src\app\employee\employee-register\employee-register.component.html را گشوده و به نحو ذیل تکمیل می‌کنیم:
<h3>Angular Forms</h3>
<form #form="ngForm">
    <input type="text" placeholder="Name">
    <button type="submit">Ok</button>
</form>

form.pristine: {{ form.pristine }}
زمانیکه المان فرم به صفحه اضافه می‌شود، Angular به صورت خودکار دایرکتیو مرتبطی را به فرم اضافه می‌کند. برای دسترسی به این دایرکتیو نیاز است یک template reference variable را تعریف کرد. برای مثال "form="ngForm#  به معنای تعریف متغیر form است که به دایرکتیو توکار ngForm متصل شده‌است و اکنون حاوی وهله‌ای از این دایرکتیو می‌باشد. به همین جهت است که امکان دسترسی به اطلاعات این وهله توسط درج form.pristine در همان قالب وجود دارد.
خاصیت pristine مشخص می‌کند که آیا فرم توسط کاربر تغییر یافته‌است یا خیر؟


مقدار خاصیت pristine در ابتدای کار true است؛ به این معنا که هنوز تغییری در آن اعمال نشده‌است.

یک نکته: ممکن است در حین توسعه‌ی برنامه، خطای ذیل را در کنسول developer tools مرورگرها مشاهده کنید:
 There is no directive with "exportAs" set to "ngForm"
این دایرکتیو تنها زمانی قابل دسترسی است که در قسمت imports ماژول جاری که با آن کار می‌کنید، تعریف FormsModule را به همان نحوی که در انتهای قسمت قبل بررسی کردیم (قسمت «افزودن ماژول فرم‌ها به برنامه»)، افزوده باشید.

در ادامه، در همین فرمی که تعاریف آن‌را در بالا مشاهده می‌کنید، اطلاعاتی را وارد نمائید. هنوز هم مقدار خاصیت pristine مساوی true است. علت اینجا است که هنوز به Angular اعلام نکرده‌ایم که کدام فیلد یا فیلدهای فرم را باید تحت نظر قرار دهد. برای این منظور ابتدا به المان تعریف شده نامی را انتساب داده و سپس دایرکتیو ngModel را نیز به انتهای تعاریف آن اضافه می‌کنیم:
<h3>Angular Forms</h3>
<form #form="ngForm">
    <input type="text" placeholder="Name" name="name" ngModel>
    <button type="submit">Ok</button>
</form>

form.pristine: {{ form.pristine }}

اکنون اگر مقدار فرم را تغییر دهیم، مشاهده خواهیم کرد که مقدار خاصیتpristine  به false تغییر می‌کند:


یک نکته: زمانیکه دایرکتیو ngModel ذکر می‌شود، تعریف name المان متناظر با آن، الزامی است؛ در غیراینصورت خطای ذیل را در کنسول developer tools مرورگرها مشاهده خواهید کرد:
 Error: If ngModel is used within a form tag, either the name attribute must be set or the form
control must be defined as 'standalone' in ngModelOptions.


خاموش کردن اعتبارسنجی توکار مرورگرها

یکی از کارهایی را که نیاز است در حین کار با فرم‌ها انجام داد، خاموش کردن اعتبارسنجی توکار مرورگرها است. فرض کنید ویژگی معتبر و استاندارد required را به یکی از المان‌های ورودی اضافه کرده‌اید:
<input type="text" required placeholder="Name" name="name" ngModel>
در این حالت اگر برنامه را اجرا کنید و بدون تکمیل این فیلد بر روی دکمه‌ی ارسال فرم کلیک نمائید، به ازای مرورگرهای مختلف، پیام انگلیسی «لطفا این فیلد را تکمیل کنید» ظاهر خواهد شد و هر کدام شکل متفاوتی را دارند که جزئیات آن‌ها را نمی‌توان تغییر داد و یا سفارشی سازی کرد. به این مورد، browser validation می‌گویند. به همین جهت برای خاموش کردن این اعتبارسنجی توکار مرورگرها و ارائه‌ی تجربه‌ی کاربری یکنواخت و یکدستی در تمام مرورگرها، نیاز است ویژگی novalidate را به تگ فرم اضافه کرد:
<form #form="ngForm" novalidate>
هر دوی ویژگی‌های novalidate و یاrequired ، جزو استاندارد HTML هستند و ارتباطی به Angular ندارند.


بهبود ظاهر فرم توسط اعمال شیوه‌نامه‌های بوت استرپ

در قسمت قبل، در ابتدای کار تدارک ساختار مثال این سری، بوت استرپ را نیز نصب و تنظیم کردیم. در ادامه می‌خواهیم اندکی ظاهر این فرم را بر اساس شیوه‌نامه‌های بوت استرپ بهبود ببخشیم:
<div class="container">
    <h3>Angular Forms</h3>
    <form #form="ngForm" novalidate>
        <div class="form-group">
            <label>First Name</label>
            <input type="text" class="form-control" required name="firstName" ngModel>
        </div>
        <div class="form-group">
            <label>Last Name</label>
            <input type="text" class="form-control" required name="lastName" ngModel>
        </div>
        <button class="btn btn-primary" type="submit">Ok</button>
    </form>
</div>

form.pristine: {{ form.pristine }}


- برای افزودن بوت استرپ نیازی نیست تا شیوه‌نامه‌ی آن‌را به صورت دستی به Index.html برنامه اضافه کرد. همینقدر که ارجاعی از آن در فایل angular-cli.json. در قسمت شیوه‌نامه‌های آن وجود داشته باشد، به صورت خودکار در bundle نهایی تولید شده‌ی توسط سیستم ساخت برنامه‌ی Angular CLI ظاهر خواهد شد.
- در اینجا ابتدا فرم خود را در داخل یک container قرار داده‌ایم. این مورد سبب می‌شود تا محتوای آن به میانه‌ی صفحه منتقل شود.
- سپس شیوه‌نامه‌ی btn به دکمه‌ی ارسال فرم اضافه شده‌است تا شکل دکمه‌های بوت استرپ را پیدا کند.
- سپس هر فیلد ورودی داخل یک div با کلاس form-group محصور می‌شود و هر کنترل، کلاس form-control را خواهد یافت.


افزودن سایر المان‌های ورودی به فرم

تا اینجا دو text box را به فرم اضافه کرده‌ایم. در ادامه می‌خواهیم المان‌های دیگری را نیز تعریف کنیم:

افزودن Check boxes

        <div class="checkbox">
            <label>
                <input type="checkbox" name="is-full-time" ngModel> Full Time Employee
            </label>
        </div>
چون با بوت استرپ کار می‌کنیم، نیاز است المان ورودی از نوع checkbox را داخل یک div با کلاس checkbox محصور کنیم. سپس یک label را تعریف کرده و Input را داخل آن قرار دهیم. در اینجا نیز همانند سایر المان‌ها نیاز است نامی را به آن انتساب داده و سپس دایرکتیو ngModel را قید نمود تا Angular این کنترل را تحت نظر قرار دهد.


افزودن Radio buttons

        <label>Payment Type</label>
        <div class="radio">
            <label>
                <input type="radio" name="pay-type" value="FullTime" checked>
                Full Time
            </label>
        </div>
        <div class="radio">
            <label>
                <input type="radio" name="pay-type" value="PartTime">
                Part Time
            </label>
        </div>
Radio buttons نیز شبیه به Check boxها تعریف می‌شوند. در اینجا نیز یک div با کلاس radio و سپس label ایی که المان ورودی از نوع radio داخل آن قرار می‌گیرد، افزوده خواهد شد. فقط در اینجا باید دقت داشت که گروه بندی این المان‌ها بر اساس نام آن‌ها انجام می‌شود. به همین جهت است که نام این دو المان یکی وارد شده‌است. همچنین باید value آن‌را نیز تنظیم کرد. این مقداری است که در نهایت به سرور ارسال خواهد شد.


افزودن Drop downs

        <div class="form-group">
            <label>Primary Language</label>
            <select class="form-control">
                <option *ngFor="let lang of languages">
                    {{ lang }}
                </option>
            </select>
        </div>
در اینجا از المان select برای تشکیل یک drop down استفاده می‌کنیم و نحوه‌ی تعریف آن بسیار شبیه است به تعریف text boxهایی که داخل form-group محصور شده و همچنین کلاس form-control را پیدا می‌کنند.
اما قسمت مهم آن، اطلاعاتی است که قرار است در این drop down نمایش داده شوند. این اطلاعات را می‌توان از آرایه‌ی languages گرفت و سپس توسط یک ngFor به المان select اضافه کرد. بنابراین باید به فایل employee-register.component.ts مراجعه کرده و آرایه‌ی languages را به آن افزود:
export class EmployeeRegisterComponent implements OnInit {
  languages = ["Persian", "English", "Spanish", "Other"];
کاری که در اینجا انجام می‌شود، تکرار المان option توسط ngFor است. برای مثال در اینجا 4 بار المان option توسط عناصر آرایه‌ی زبان‌ها در داخل المان select تکرار خواهد شد. به عبارتی select نهایی رندر شده‌ی در صفحه، چنین شکلی را پیدا می‌کند:
<select class="form-control">
  <option>Persian</option>
  <option>English</option>
  <option>Spanish</option>
  <option>Other</option>
</select>

تا اینجا فرم تشکیل شده‌ی ما چنین نمایی را پیدا می‌کند:


در قسمت بعد این فرم را توسط مباحث data binding و بررسی نحوه‌ی دسترسی به اطلاعات آن در کامپوننت مرتبط، تکمیل خواهیم کرد.



کدهای کامل این قسمت را از اینجا می‌توانید دریافت کنید: angular-template-driven-forms-lab-02.zip
برای اجرای آن فرض بر این است که پیشتر Angular CLI را نصب کرده‌اید. سپس از طریق خط فرمان به ریشه‌ی پروژه وارد شده و دستور npm install را صادر کنید تا وابستگی‌های آن دریافت و نصب شوند. در آخر با اجرای دستور ng serve -o برنامه ساخته شده و در مرورگر پیش فرض سیستم نمایش داده خواهد شد.
اشتراک‌ها
نگاهی به نوع‌های جدید DateOnly و TimeOnly در NET 6.

In .NET 6 (preview 4), two long-awaited types have been introduced as part of the core library. DateOnly and TimeOnly allow developers to represent either the date or time portion of a DateTime. These two new types are structs (value types) and may be used when your code deals with date or time concepts independently. Both types can be found in the System namespace. Using these new types may align well with how databases allow similar data to be represented. Specifically, these types align well with the SQL Server date and time data types. 

نگاهی به نوع‌های جدید DateOnly و TimeOnly در NET 6.
اشتراک‌ها
15 کتاب الکترونیکی برای طراحان و توسعه دهندگان
1.Pocket Guide to Writing SVG
2.Speaking JavaScript
3.Adaptive Web Design
4. 27 Page Type Classification eBook
5. 11 Things to Do with Every New WordPress Install
6. Building Web Apps with Go
7. Go Mobile With WordPress
8. HTML Canvas Deep Dive 
9. 10 Keys to Great Landing Pages
10. Book of Speed
11. A Practical Guide to Designing for the Web
12. PHP: The Right Way
13. Essential Career Advice for Developers
14. So You Want To Be A Freelancer?
15. Magic of CSS
15 کتاب الکترونیکی برای طراحان و توسعه دهندگان
اشتراک‌ها
2.Visual Studio 2019 RC منتشر شد

Top Issues Fixed in Visual Studio 2019 RC.2

2.Visual Studio 2019 RC منتشر شد
مطالب
Minimal API's در دات نت 6 - قسمت چهارم - تدارک مقدمات معماری بر اساس ویژگی‌ها
در معماری vertical slices با features سر و کار داریم؛ برای مثال برنامه‌ی ما دو ویژگی نویسنده‌ها و بلاگ‌ها را خواهد داشت و هر ویژگی، کاملا متکی به خود است. برای نمونه هر ویژگی می‌تواند به همراه یک ماژول باشد که به صورت مستقل، تمام سرویس‌ها، endpoints و میان‌افزارهای مورد نیاز خودش را ثبت می‌کند. در این معماری، تمام قسمت‌های مورد نیاز جهت کارکرد یک ویژگی، در کنار هم قرار می‌گیرند تا یافتن آن‌ها و درک ارتباطات بین آن‌ها ساده‌تر شود.


تعریف ساختار ماژول‌های ویژگی‌های معماری vertical slices

برای تعریف ساختار ماژولی که کار ثبت تمام نیازمندی‌های یک ویژگی را انجام می‌دهد، مانند ثبت سرویس‌ها، endpoints و میان‌افزارها، ابتدا پوشه‌ای به نام Contracts را به پروژه‌ی Api اضافه می‌کنیم؛ با این اینترفیس:
namespace MinimalBlog.Api.Contracts;

public interface IModule
{
    IEndpointRouteBuilder RegisterEndpoints(IEndpointRouteBuilder endpoints);
}


ثبت خودکار ماژول‌های برنامه در ابتدای اجرای آن

پس از تعریف این قرارداد، اکنون می‌خواهیم هر ماژولی که در برنامه، اینترفیس فوق را پیاده سازی می‌کند، در ابتدای اجرای برنامه به صورت خودکار، یافت شده و اطلاعات آن به سیستم اضافه شود. برای این منظور متدهای الحاقی زیر را تعریف می‌کنیم:
public static class ServiceCollectionExtensions
{
    public static IServiceCollection AddApplicationServices(this IServiceCollection services,
        WebApplicationBuilder builder)
    {
        // ...

        builder.Services.AddAllModules(typeof(Program));

        return services;
    }

    private static void AddAllModules(this IServiceCollection services, params Type[] types)
    {
        // Using the `Scrutor` to add all of the application's modules at once.
        services.Scan(scan =>
            scan.FromAssembliesOf(types)
                .AddClasses(classes => classes.AssignableTo<IModule>())
                .AsImplementedInterfaces()
                .WithSingletonLifetime());
    }
}
این کلاس ساختار ساده‌ای دارد؛ ابتدا در متد AddAllModules، اسمبلی جاری جهت یافتن کلاس‌های پیاده سازی کننده‌ی اینترفیس IModule، اسکن می‌شود؛ با استفاده از کتابخانه‌ی Scrutor.
سپس کلاس‌های ثبت شده که هم اکنون جزئی از سیستم تزریق وابستگی‌های برنامه هستند، یافت شده و متد RegisterEndpoints آن‌ها فراخوانی می‌شوند تا دیگر نیازی نباشد به ازای هر ماژول، یکبار ثبت دستی این موارد در کلاس Program انجام شود.
using MinimalBlog.Api.Contracts;

namespace MinimalBlog.Api.Extensions;

public static class ModuleExtensions
{
    public static WebApplication RegisterEndpoints(this WebApplication app)
    {
        if (app == null)
        {
            throw new ArgumentNullException(nameof(app));
        }

        var modules = app.Services.GetServices<IModule>();
        foreach (var module in modules)
        {
            module.RegisterEndpoints(app);
        }

        return app;
    }
}
بنابراین در ادامه به کلاس Program مراجعه کرد و متد عمومی کلاس فوق را در آن به صورت app.RegisterEndpoints فراخوانی می‌کنیم:
using MinimalBlog.Api.Extensions;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddApplicationServices(builder);

var app = builder.Build();
app.ConfigureApplication();
app.RegisterEndpoints();

app.Run();
این چند سطر، کل محتوای فایل Program.cs برنامه را تشکیل می‌دهند.


ایجاد اولین Feature برنامه؛ ویژگی نویسندگان

برای تعریف اولین ویژگی برنامه که مختص به نویسندگان است، پوشه‌های جدید Features\Authors را در برنامه‌ی Api ایجاد می‌کنیم.
- اولین کاری را که در ادامه انجام خواهیم داد، انتقال فایل AuthorDto.cs که در قسمت قبل ایجاد کردیم، به درون این پوشه‌ی جدید است.
- سپس ماژول نویسندگان را به صورت زیر به آن اضافه می‌کنیم:
namespace MinimalBlog.Api.Features.Authors;

public class AuthorModule : IModule
{
    public IEndpointRouteBuilder RegisterEndpoints(IEndpointRouteBuilder endpoints)
    {
        endpoints.MapGet("/api/authors", async (MinimalBlogDbContext ctx) =>
        {
            var authors = await ctx.Authors.ToListAsync();
            return authors;
        });

        endpoints.MapPost("/api/authors", async (MinimalBlogDbContext ctx, AuthorDto authorDto) =>
        {
            var author = new Author();
            author.FirstName = authorDto.FirstName;
            author.LastName = authorDto.LastName;
            author.Bio = authorDto.Bio;
            author.DateOfBirth = authorDto.DateOfBirth;

            ctx.Authors.Add(author);
            await ctx.SaveChangesAsync();

            return author;
        });

        return endpoints;
    }
}
در اینجا ماژول نویسندگان را که با پیاده سازی قرارداد IModule تشکیل شده‌است، مشاهده می‌کنید. در متد RegisterEndpoints آن، دو endpoints تعریف شده‌ی در کلاس Program برنامه را در قسمت قبل، Cut کرده و به اینجا منتقل کرده‌ایم. بنابراین اکنون کلاس Program، دیگر به همراه تعریف مستقیم هیچ endpoint ای نیست و خلوت شده‌است. هدف از Features هم دقیقا همین است تا هر ویژگی برنامه، متکی به خود بوده و مستقل باشد؛ به همراه تمام تعاریف مورد نیاز جهت کار با آن در یک محل مشخص (مانند انتقال فایل Dto مربوط به آن، به درون همین پوشه). مزیت این روش، درک ساده‌تر اجزای مرتبط و یافتن سریعتر ارتباطات قسمت‌های یک ویژگی خاص است. در آینده اگر مشکلی رخ داد و باگی بروز پیدا کرد، دقیقا می‌دانیم که محدوده‌ای که باید مورد بررسی قرار گیرد، کجاست و این محدوده، کوچک و متکی به خود است و در بین چندین پروژه‌ی مختلف، پراکنده نشده‌است.
کار نمونه سازی و اجرای متدهای این ماژول‌ها نیز توسط متدهای الحاقی کلاس ModuleExtensions، در ابتدای اجرای برنامه به صورت خودکار انجام می‌شود و نیازی به شلوغ کردن کلاس Program برای ثبت دستی آن‌ها نیست.


افزودن AutoMapper و MediatR به پروژه‌ی Api

در ادامه برای ساده سازی کار نگاشت‌های Dtoهای برنامه به مدل‌های دومین آن، از AutoMapper استفاده خواهیم کرد؛ همچنین از MediatR نیز برای پیاده سازی الگوی CQRS که در قسمت بعدی پیگیری خواهد شد. بنابراین در ابتدا بسته‌های نیوگت این دو را به پروژه‌ی Api اضافه می‌کنیم:
<Project Sdk="Microsoft.NET.Sdk.Web">
  <ItemGroup>
    <PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="11.0.0" />    
    <PackageReference Include="MediatR.Extensions.Microsoft.DependencyInjection" Version="10.0.1" />  
  </ItemGroup>
</Project>
سپس به کلاس ServiceCollectionExtensions مراجعه کرده و تعاریف ثبت سرویس‌های این دو را نیز اضافه می‌کنیم:
public static class ServiceCollectionExtensions
{
    public static IServiceCollection AddApplicationServices(this IServiceCollection services,
        WebApplicationBuilder builder)
    {
        // ...

        builder.Services.AddMediatR(typeof(Program));
        builder.Services.AddAutoMapper(typeof(Program));

        return services;
    }
}
اکنون می‌توان اولین Profile مربوط به AutoMapper را که کار نگاشت AuthorDto به Author و برعکس را انجام می‌دهد، به صورت زیر تهیه کنیم:
using AutoMapper;
using MinimalBlog.Domain.Model;

namespace MinimalBlog.Api.Features.Authors;

public class AuthorProfile : Profile
{
    public AuthorProfile()
    {
        CreateMap<AuthorDto, Author>().ReverseMap();
    }
}
این فایل نیز درون پوشه‌ی Features\Authors قرار می‌گیرد.
اشتراک‌ها
کتاب رایگان Implementing a Custom Language Succinctly

Custom languages provide many benefits, but many people fear the complexity that comes with trying to deploy them. Author Vassili Kaplan sweeps away the obstacles and shows how custom languages are a tool within reach of any developer. With Implementing a Custom Language Succinctly, readers will discover just how much they can accomplish with the skills they already have.

Table of Contents
  1. Introduction
  2. The Split-and-Merge Algorithm
  3. Basic Control Flow Statements
  4. Functions, Functions, Functions
  5. Exceptions and Custom Functions
  6. Operators, Arrays, and Dictionaries
  7. Localization
  8. Testing and Advanced Topics 
کتاب رایگان Implementing a Custom Language Succinctly