اشتراک‌ها
اکستنشنی برای پیاده سازی CQRS , EventSourcing در Orleans

Orleankka is a functional extension for Microsoft Orleans framework. It provides a message-based API similar to Akka/ProtoActor, carefully layered on top of Microsoft Orleans (that's what in a name). Orleankka is an excellent choice for use-cases which can benefit from composable, uniform communication interface, such as CQRS, event-sourcing, FSM, etc.

اکستنشنی برای پیاده سازی CQRS , EventSourcing در Orleans
اشتراک‌ها
آکادمی برای روزلین
The Roslyn Academy is an online community dedicated to writing code and building applications based on the Microsoft .NET Compiler Platform.We feature passionate developers and expert people about the Roslyn APIs. 
آکادمی برای روزلین
اشتراک‌ها
شرکت در نظرسنجی امکانات بومی سازی تیم Angular
Hello! I work for the Angular core team on internationalization (i18n) and we are trying to get a better idea of the things that we need to improve/focus on in Angular regarding i18n. I created this survey: https://goo.gl/forms/0BIXXVP58RqbzzBM2 If you care about internationalization, please take 5mn to do it! Thanks!
شرکت در نظرسنجی امکانات بومی سازی تیم Angular
مطالب
بهبود SEO برنامه‌های Angular
یکی از موارد مهم بهینه سازی صفحات سایت برای موتورهای جستجو، افزودن عنوانی مناسب، به همراه توضیحات و واژه‌های کلیدی، twitter card ،Facebook Graph و امثال آن‌ها است. برای این منظور Angular به همراه سرویس‌هایی است که امکان افزودن این متاتگ‌ها را به صورت پویا مهیا می‌کنند.


آشنایی با امکانات بسته‌ی angular/platform-browser@

در ماژول angular/platform-browser@، دو سرویس Meta و Title، امکان تغییر پویای متاتگ‌های صفحه‌ی جاری را مهیا می‌کنند. برای نمونه فرض کنید قصد دارید یک چنین متاتگ‌هایی را به صفحه‌ی جاری اضافه کنید:
<head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="icon" type="image/x-icon" href="favicon.ico">
    <title>newTitle ...</title>
    <base href="/">
    <meta name="description" content="Angular meta service">
<meta name="author" content="DNT">
<meta name="keywords" content="Angular, Meta Service">
<meta name="twitter:card" content="summary">
<meta name="twitter:site" content="@my_site">
<meta name="twitter:title" content="Front-end Web Development">
<meta name="twitter:description" content="Learn frontend web development...">
<meta name="twitter:image" content="https://site/images/image.png">
<meta name="author" content="Other Author">
</head>
قدم اول انجام اینکار، تزریق سرویس‌های توکار Meta و Title به سازنده‌ی کامپوننت جاری است:
import { Component, OnInit } from "@angular/core";
import { Meta, Title } from "@angular/platform-browser";

@Component({
  selector: "app-seo-tests",
  templateUrl: "./seo-tests.component.html",
  styleUrls: ["./seo-tests.component.css"]
})
export class SeoTestsComponent implements OnInit {

  constructor(private metaService: Meta, private titleService: Title) {
  }
در ادامه متدهای مختلف این سرویس‌ها را بررسی خواهیم کرد:

افزودن یک یا چند متاتگ

متد addTag سرویس Meta، کار افزودن پویای یک متا تگ جدید را به همراه ویژگی‌های name و content آن، انجام می‌دهد. در ذیل چندین مثال از آن‌را مشاهده می‌کنید. در اینجا یا می‌توان از متد addTag استفاده کرد که تنها یک متاتگ را به صفحه اضافه می‌کند و یا از متد addTags کمک گرفت که می‌تواند آرایه‌ای از متاتگ‌ها را به صورت پویا به صفحه‌ی جاری اضافه کند:
    // addTag & addTags
    this.metaService.addTag({ name: "description", content: "How to optimize your Angular App for search engine and other crawlers." });
    this.metaService.addTag({ name: "author", content: "DNT" });
    this.metaService.addTag({ name: "keywords", content: "Angular, Meta Service" });
    // Or
    this.metaService.addTags([
      { name: "description", content: "How to optimize your Angular App for search engine and other crawlers." },
      { name: "author", content: "DNT" },
      { name: "keywords", content: "Angular, Meta Service" }
    ], false); // --> forceCreation = false

    this.metaService.addTag({ name: "twitter:card", content: "summary_large_image" });
    this.metaService.addTag({ name: "twitter:site", content: "@my_site" });
    this.metaService.addTag({ name: "twitter:title", content: "Front-end Web Development" });
    this.metaService.addTag({ name: "twitter:description", content: "Learn frontend web development..." });
    this.metaService.addTag({ name: "twitter:image", content: "https://site/images/image.png" });
    // Or
    this.metaService.addTags([
      { name: "twitter:card", content: "summary_large_image" },
      { name: "twitter:site", content: "@my_site" },
    ], false); // --> forceCreation = false
هر دو متد addTag و addTags دارای پارامتر boolean دومی به نام forceCreation نیز هستند. برای مثال اگر این پارامتر را به true تنظیم کنید، این متاتگ حتی اگر وجود هم داشته باشد، یکبار دیگر به صفحه اضافه خواهد شد.


دریافت محتوای متاتگ‌های موجود

با استفاده از متد getTag می‌توان یک متاتگ مشخص را به صورت HTMLMetaElement دریافت کرد:
    // getTag & getTags
    const viewport = this.metaService.getTag("name=viewport");
    if (viewport) {
      console.log(viewport.content); // width=device-width, initial-scale=1
    }
    const author = this.metaService.getTag("name=author");
    if (author) {
      console.log(author.content); // DNT
    }

    this.metaService.addTag({ name: "author", content: "DNT" });
    this.metaService.addTag({ name: "author", content: "Other Author" }, true);
    const authors = this.metaService.getTags("name=author");
    console.log(authors[0]); // <meta name="author" content="DNT">
    console.log(authors[1]); // <meta name="author" content="Other Author">
کار متد getTags بازگشت تمام متاتگ‌هایی با attribute-selector یکسان است. برای مثال در اینجا دوبار متاتگ author به صفحه اضافه شده‌است و خروجی getTags به همراه دو عنصر است.


به روز رسانی متاتگ‌های موجود

می‌توان از متد updateTag برای تغییر محتوای متاتگی موجود، استفاده کرد:
    // updateTag
    this.metaService.addTag({ name: "twitter:card", content: "summary_large_image" });
    this.metaService.updateTag({ name: "twitter:card", content: "summary" }, `name='twitter:card'`);

    this.metaService.updateTag({ name: "description", content: "Angular meta service" });
در اینجا اگر پارامتر اختیاری دوم ذکر نشود، جستجوی یافتن عناصر، بر اساس name ذکر شده صورت می‌گیرد و سپس content آن‌ها به روز می‌شود.


حذف تگ‌های موجود

در اینجا می‌توان از دو متد removeTag که یک attribute-selector را دریافت می‌کند و یا removeTagElement که یک HTMLMetaElement را توسط متد getTag دریافت می‌کند، برای حذف کامل این تگ‌ها استفاده کرد:
    // removeTag & removeTagElement
    this.metaService.removeTag("charset");
    // Or
    const chartsetTag = this.metaService.getTag("charset");
    if (chartsetTag) {
      this.metaService.removeTagElement(chartsetTag);
    }


تنظیم عنوان صفحه‌ی جاری

سرویس توکار دیگری به نام Title امکان تغییر عنوان صفحه‌ی جاری را به صورت پویا میسر می‌کند:
    // Setting the browser page Title in an Angular app
    const currentTitle = this.titleService.getTitle();
    console.log(currentTitle);
    this.titleService.setTitle("newTitle ...");
متد getTitle، عنوان فعلی صفحه را باز می‌گرداند و متد setTitle، این عنوان را به روز رسانی می‌کند.


طراحی سرویسی برای افزودن پویای متاتگ‌ها به صفحات مختلف سایت

می‌توان شبیه به مطلب «نمایش Breadcrumbs در برنامه‌های Angular» به قسمت data مسیریابی، اطلاعات عنوان صفحه و همچنین  metaTags آن‌را اضافه کرد:
const routes: Routes = [
  {
    path: "seo", component: SeoTestsComponent,
    data: {
      title: "Page Title",
      metaTags: {
        description: "Page Description or some content here",
        keywords: "some, keywords, here, separated, by, a comma"
      }
    }
  }
];
سپس سرویسی را طراحی نمود که با پایان یافتن مسیریابی فعلی، این تنظیمات را به صورت خودکار انجام دهد و نیازی نباشد تا مدام به تمام کامپوننت‌ها، سرویس‌های Meta و Title را به صورت دستی اضافه کرد و این اطلاعات را تغییر داد.
به همین جهت سرویس SEO را در مسیر src\app\core\seo-service.ts به صورت ذیل ایجاد می‌کنیم:
import { Injectable } from "@angular/core";
import { Title, Meta } from "@angular/platform-browser";
import { Router, NavigationEnd, ActivatedRouteSnapshot } from "@angular/router";

@Injectable()
export class SeoService {

  constructor(private titleService: Title, private metaService: Meta, private router: Router) { }

  enableSeo() {
    this.router.events
      .filter(event => event instanceof NavigationEnd)
      .distinctUntilChanged()
      .subscribe(() => {
        this.addMetaData(this.router.routerState.snapshot.root);
      });
  }

  private addMetaData(root: ActivatedRouteSnapshot): void {
    if (root.children && root.children.length) {
      this.addMetaData(root.children[0]);
    } else if (root.data) {
      this.setTitle(root.data);
      this.setMetaTags(root.data);
    }
  }

  private setMetaTags(routeData: { [name: string]: any; }) {
    const routeDataMetaTagsKey = "metaTags";
    const metaTags = routeData[routeDataMetaTagsKey];
    if (!metaTags) { return; }
    for (const tag in metaTags) {
      if (metaTags.hasOwnProperty(tag)) {
        const newTag = { name: tag, content: metaTags[tag] };
        console.log("new tag", newTag);
        this.metaService.addTag(newTag);
      }
    }
  }

  private setTitle(routeData: { [name: string]: any; }) {
    const routeDataTitleKey = "title";
    const title = routeData[routeDataTitleKey];
    if (title) {
      console.log("new title", title);
      this.titleService.setTitle(title);
    }
  }
}
توضیحات:
در اینجا در ابتدای کار مشترک رخ‌داد NavigationEnd سیستم مسیریابی خواهیم شد:
    this.router.events
      .filter(event => event instanceof NavigationEnd)
      .distinctUntilChanged()
      .subscribe(() => {
        this.addMetaData(this.router.routerState.snapshot.root);
      });
هر زمانیکه رخ‌داد مرور صفحه‌ی جاری به پایان رسید، بر اساس مسیر ریشه‌ی آن، متد addMetaData فراخوانی می‌شود. این متد، یک متد بازگشتی است. از این جهت که مسیر جاری می‌تواند حاصل مرور یک مسیر والد و سپس چندین مسیر تو در توی فرزند و والد آن باشد.
سپس در این متد خاصیت data مسیرنهایی را خوانده و کلیدهای title و metaTags آن‌را استخراج می‌کنیم و سپس توسط متدهای this.titleService.setTitle و this.metaService.addTag، این عنوان و متاتگ‌های جدید را به صورت پویا به صفحه اضافه خواهیم کرد.

پس از تعریف این سرویس، برای معرفی آن به برنامه، ابتدا آن‌را به قسمت providers مربوط به CoreModule اضافه می‌کنیم:
import { SeoService } from "./seo-service";

@NgModule({
  providers: [
    SeoService
  ]
})
export class CoreModule {}
و در آخر به فایل app.component.ts مراجعه کرده و این سرویس را فعالسازی می‌کنیم:
import { SeoService } from "./core/seo-service";

export class AppComponent {
  constructor(private seoService: SeoService) {
    this.seoService.enableSeo();
  }
}
از این پس تمام مسیرهای برنامه به صورت خودکار تحت نظر قرار گرفته و درصورتیکه خاصیت data آن‌ها دارای کلیدهای title و metaTags باشند، به صورت خودکار پردازش خواهند شد.



کدهای کامل این قسمت را از اینجا می‌توانید دریافت کنید.
اشتراک‌ها
TypeScript 4.1 Beta منتشر شد

Let’s get a look at what 4.1 has in store for us!
- Template Literal Types
- Key Remapping in Mapped Types
- Recursive Conditional Types
- --noUncheckedIndexedAccess
- paths without baseUrl
- checkJs Implies allowJs
- React 17 JSX Factories
- Editor Support for the JSDoc @see Tag
- Breaking Changes 

TypeScript 4.1 Beta منتشر شد
اشتراک‌ها
معماری های رایج برنامه های وب

Most traditional .NET applications are deployed as single units corresponding to an executable or a single web application running within a single IIS appdomain. This approach is the simplest deployment model and serves many internal and smaller public applications very well. However, even given this single unit of deployment, most non-trivial business applications benefit from some logical separation into several layers. 

معماری های رایج برنامه های وب
اشتراک‌ها
Datepicker متن‌باز شمسی برای React

react-datepicker2 کتابخانه‌ای متن‌باز با قابلیت پشتیبانی از تاریخ میلادی و شمسی بر پایه React است.
برخی از ویژگی‌های جدید نسبت به کتابخانه react-persian-datepicker :

  • حذف وابستگی به css-modules
  • پشتیبانی از تاریخ میلادی
  • افزوده شدن time-picker (انتخاب کننده ساعت) به عنوان یک کامپوننت داخلی

Datepicker متن‌باز شمسی برای React
نظرات مطالب
React 16x - قسمت 1 - معرفی و شروع به کار
جهت اطلاع امروز دستور زیر، قالب پروژه را ایجاد نکرد:
create-react-app xxx

به همین علت، حذف و نصب مجدد را انجام دادم که متوجه شدم دستور نصب هم کار نکرد.
npm i -g create-react-app

به نظر میرسد طریقه کار با آن به شکل زیر تغییر کرده است:
npx create-react-app my-app
دستور npx  از نسخه npm 5.2 به بعد در دسترس است.