Asp.Net Core WebSockets Vs SignalR. Which should you use? (Full Course)
In this video we build 2 separate chat applications, one using Asp.Net Core WebSockets and the other using SignalR, allowing you to compare approaches and decide on which one works best for you. In both cases we build them with C#, .NET Core and JavaScript. You’ll also learn about:
- .NET Core Request Pipeline
- Request Delegates
- Asynchronous Programming in .NET (Async / Await)
- Introduction to Dependency Injection
Spark is an open source computing framework for Big Data, and it’s becoming increasingly popular, especially in machine learning scenarios. In this article I’ll describe how to install Spark on a machine running a Windows OS, and explain basic Spark functionality from a .NET developer’s point of view.
انواع providers در Angular
سیستم تزریق وابستگیهای Angular، تامین کنندههای ذیل را نیز به همراه دارد:
- تامین کنندهی مقادیر که با useValue مشخص میشود.
- تامین کنندهی Factoryها که با useFactory تعریف خواهد شد.
- تامین کنندهی کلاسها که با useClass تعریف میشود.
- تامین کنندهی کلاسهایی با نامهای مستعار که توسط useExisting مشخص میشود.
یک تامین کننده مشخص میکند که سیستم تزریق کنندهی وابستگیها، با درخواست توکن/کلیدی مشخص، چه وابستگی را باید وهله سازی کند.
تزریق وابستگیهایی از نوع ثوابت در برنامههای Angular
فرض کنید برنامهی Angular شما در مسیر دیگری نسبت به Web API سمت سرور آن قرار دارد. به همین جهت در تمام سرویسهای برنامه نیاز به تعریف مسیر پایهی Web API مانند API_BASE_HREF را خواهید داشت. یک روش حل این مساله، تعریف این ثابت به صورت یک وابستگی و سپس تزریق آن به کلاسهای سرویسها و یا کامپوننتهای برنامه است:
@NgModule({ imports: [ CommonModule, InjectionBeyondClassesRoutingModule ], declarations: [TestProvidersComponent], providers: [ { provide: "API_BASE_HREF", useValue: "http://localhost:5000" }, { provide: "APP_BASE_HREF", useValue: document.location.pathname }, { provide: "IS_PROD", useValue: true }, { provide: "APIKey", useValue: "XYZ1234ABC" }, { provide: "Random", useValue: Math.random() }, { provide: "emailApiConfig", useValue: Object.freeze({ apiKey: "email-key", context: "registration" }) }, { provide: "languages", useValue: "en", multi: true }, { provide: "languages", useValue: "fa", multi: true } ] }) export class InjectionBeyondClassesModule { }
- در این مثال، حالتهای مختلفی از تامین کنندهی useValue را نیز مشاهده میکنید. انتساب یک رشته، یک مقدار boolean و یا یک مقدار که در زمان انتساب محاسبه خواهد شد مانند Math.random.
- همچنین در اینجا میتوان در قسمت useValue مانند emailApiConfig، یک شیء را نیز تعریف کرد. علت استفادهی از Object.freeze، تعریف این شیء به صورت read only است.
- در حین تعریف provideها اگر کلید توکن بکار رفته یکی باشد، آخرین مقدار، مابقی را بازنویسی میکند؛ مانند حالت languages که در اینجا دوبار تعریف شدهاست. اما با ذکر خاصیت multi، میتوان به کلید languages به صورت یک آرایه دسترسی یافت و در این حالت مقادیر آن بازنویسی نمیشوند.
اکنون برای استفادهی از این توکنهای تعریف شده توسط سیستم تزریق وابستگیها، میتوان به صورت ذیل عمل کرد:
import { Component, OnInit, Inject } from "@angular/core"; import { inject } from "@angular/core/testing"; @Component({ selector: "app-test-providers", templateUrl: "./test-providers.component.html", styleUrls: ["./test-providers.component.css"] }) export class TestProvidersComponent implements OnInit { constructor( @Inject("API_BASE_HREF") public apiBaseHref: string, @Inject("APP_BASE_HREF") public appBaseHref: string, @Inject("IS_PROD") public isProd: boolean, @Inject("APIKey") public apiKey: string, @Inject("Random") public random: string, @Inject("emailApiConfig") public emailApiConfig: any, @Inject("languages") public languages: string[] ) { } ngOnInit() { } }
<h1> Injection Beyond Classes </h1> <div class="alert alert-info"> <ul> <li>API_BASE_HREF: {{apiBaseHref}}</li> <li>APP_BASE_HREF: {{appBaseHref}}</li> <li>IS_PROD: {{isProd}}</li> <li>APIKey: {{apiKey}}</li> <li>Random-1: {{random}}</li> <li>Random-2: {{random}}</li> <li>emailApiConfig {{emailApiConfig | json}}</li> <li>languages: {{languages | json}}</li> </ul> </div>
در اینجا همانطور که مشاهده میکنید، languages از نوع multi: true به یک آرایه تبدیل شدهاست و یا emailApiConfig نیز یک شیء است که توسط کلیدهای آن میتوان به مقادیر متناظر آن دسترسی یافت. Random نیز تنها یکبار دریافت شدهاست و مهم نیست که چندبار صدا زده شود؛ همواره مقدار آن مساوی اولین مقداری است که در زمان انتساب دریافت میکند.
تزریق تنظیمات برنامه توسط تامین کنندهی مقادیر
یک نمونه از تزریق شیء emailApiConfig: any را در مثال فوق ملاحظه کردید. روش بهتر و نوع دار آن به صورت ذیل است. ابتدا یک فایل جدید thismodule.config.ts یا app.config.ts را ایجاد میکنیم:
import { InjectionToken } from "@angular/core"; export let APP_CONFIG = new InjectionToken<string>("this.module.config"); export interface IThisModuleConfig { apiEndpoint: string; } export const ThisModuleConfig: IThisModuleConfig = { apiEndpoint: "http://localhost:45043/api/" };
import { InjectionToken } from '@angular/core'; export const EmailService1 = new InjectionToken<string>("EmailService"); export const EmailService2 = new InjectionToken<string>("EmailService"); console.log(EmailService1 === EmailService2); // false
سپس نوع تنظیمات را توسط اینترفیس IThisModuleConfig تعریف کردهایم (که نسبت به استفادهی از any یک پیشرفت محسوب میشود). در آخر وهلهای از این اینترفیس را به نحوی که مشاهده میکنید export کردهایم.
اکنون نحوهی تعریف تزریق وابستگی از نوع IThisModuleConfig در یک NgModule به صورت ذیل است:
import { ThisModuleConfig, APP_CONFIG } from "./thismodule.config"; @NgModule({ providers: [ { provide: APP_CONFIG, useValue: ThisModuleConfig } ] }) export class InjectionBeyondClassesModule { }
در آخر، تزریق آن به سازندهی یک کامپوننت بر اساس توکن APP_CONFIG و از نوع مشخص اینترفیس آن خواهد بود:
import { IThisModuleConfig, APP_CONFIG } from "./../thismodule.config"; @Component() export class TestProvidersComponent implements OnInit { constructor( @Inject(APP_CONFIG) public config: IThisModuleConfig ) { } ngOnInit() { } }
تزریق وابستگیها توسط تامین کنندهی Factory ها
تا اینجا useValue را بررسی کردیم. نوع دیگر تامین کنندههای قابل تعریف، useFactory هستند:
@NgModule({ providers: [ // ------ useFactory { provide: "BASE_URL", useFactory: getBaseUrl }, { provide: "RandomFactory", useFactory: randomFactory } ] }) export class InjectionBeyondClassesModule { } export function getBaseUrl() { return document.getElementsByTagName("base")[0].href; } export function randomFactory() { return Math.random(); }
روش استفادهی از آن نیز همانند توکنهای useValue است که توسط ویژگی Inject مشخص میشوند:
export class TestProvidersComponent implements OnInit { constructor( @Inject("BASE_URL") public baseUrl: string, @Inject("RandomFactory") public randomFactory: string ) { }
حالت useFactory علاوه بر امکان دریافت یک منطق سفارشی توسط یک function، امکان دریافت یک سری وابستگی را نیز دارد. فرض کنید کلاس سرویس خودرو به صورت زیر تعریف شدهاست که دارای وابستگی از نوع HttpClient تزریق شدهی در سازندهی آن است:
import { HttpClient } from "@angular/common/http"; import { Injectable } from "@angular/core"; @Injectable() export class CarService { constructor(private http: HttpClient) { } }
import { CarService } from "./car.service"; import { HttpClient } from "@angular/common/http"; @NgModule({ providers: [ // ------ useFactory { provide: "Car_Service", useFactory: carServiceFactory, deps: [HttpClient] } ] }) export class InjectionBeyondClassesModule { } export function carServiceFactory(http: HttpClient) { return new CarService(http); }
تزریق وابستگیها توسط تامین کنندهی کلاسها
تا اینجا useValue و useFactory را بررسی کردیم. نوع دیگر تامین کنندههای قابل تعریف، useClass هستند. در حالت استفادهی useClass، نام یک نوع مشخص میشود و سپس Angular وهلهای از آنرا تامین خواهد کرد. در این حالت اگر این وابستگی دارای پارامترهای تزریق شدهای در سازندهی آن باشد، آنها نیز به صورت خودکار وهله سازی میشوند.
import { CarService } from "./car.service"; @NgModule({ providers: [ // ------ useClass { provide: "Car_Service_Name1", useClass: CarService }, ] }) export class InjectionBeyondClassesModule { }
import { CarService } from "./car.service"; @NgModule({ providers: [ CarService ] }) export class InjectionBeyondClassesModule { }
تزریق وابستگیها توسط تامین کنندهی کلاسهایی با نامهای مستعار
چگونه میتوان دو تامین کننده را برای کلاسی مشابه، با توکنهایی متفاوت ایجاد کرد؟ در این حالت از useExisting استفاده میشود:
import { CarService } from "./car.service"; @NgModule({ providers: [ // ------ useClass { provide: "Car_Service_Name1", useClass: CarService }, // ------ useExisting { provide: "Car_Service_Token2", useExisting: "Car_Service_Name1" }, ] }) export class InjectionBeyondClassesModule { }
کدهای کامل این قسمت را از اینجا میتوانید دریافت کنید.
پروتکل HTTP/2
ایجاد یک Reverse Proxy در NET Core.
This article will show you how to implement a reverse proxy in C# and .NET Core to overcome specific needs that you could hardly solve with an out-of-the-box software. You can find the code of the final project on this GitHub repository.
روش مهاجرت از Moq به NSubstitute
Unit testing is an integral part of modern software development. For years, Moq has been a popular choice in the .NET ecosystem for creating mock objects. Recent concerns over Moq’s SponsorLink feature have prompted some developers to consider such a switch. In this article, we delve into why you might consider NSubstitute over Moq and how to make the transition.
An easier way to manage INotifyPropertyChanged
Custom Explicit and Implicit Operators in C#
Why does this code work?
ASP.NET MVC Model binding with implicit operators
Forgotten C# language features: implicit operator
How to fake Enums in EF 4