مطالب
آشنایی با CLR: قسمت شانزدهم
در مقاله قبلی بحث Assembly Linker را باز کردیم و یاد گرفتیم که چگونه می‌توان با استفاده از آن ماژول‌های مختلف را به یک اسمبلی اضافه کرد. در این قسمت از این سلسله مقالات  قصد داریم فایل‌های منابع (Resource) مانند مواد چندرسانه‌ای، چند زبانه و .. را به آن اضافه کنیم. یک اسمبلی حتی میتواند تنها Resource باشد.

برای اضافه کردن یک فایل به عنوان منبع، از سوئیچ [embed[resource استفاده می‌شود. این سوئیچ محتوای هر نوع فایلی را که به آن پاس شود، به فایل PE اجرایی انتقال داده و جدول ManifestResourceDef را به روز می‌کند تا سیستم از وجود آن آگاه شود.
سوئیچ [link[Resource هم برای الحاق کردن یک فایل به اسمبلی به کار می‌رود و دو جدول ManifestResourceDef و  FileDef را جهت معرفی منبع جدید و شناسایی فایل اسمبلی که حاوی این منبع است، به روز می‌کند. در این حالت فایل منبع embed نشده و باید در کنار پروژه منتشر شود.
csc هم قابلیت‌های مشابهی را با استفاده از سوئیچ‌های resource/ و link/ دارد و به روز رسانی و دیگر اطلاعات تکمیلی آن مشابه موارد بالاست.

شما حتی می‌توانید منابع یک فایل win32 را خیلی راحت و آسان به اسمبلی معرفی کنید. شما به آسانی می‌توانید مسیر یک فایل res. را با استفاده از سوئیچ win32res/ در al یا csc مشخص کنید. یا برای embed کردن آیکن یک برنامه win32 از سوئیچ win32icon/ مسیر یک فایل ICO را مشخص کنید. در ویژوال استودیو این‌کار به صورت ویژوالی در پنجره تنظمیات پروژه و برگه‌ی Application امکان پذیر است. دلیل اصلی که آیکن برنامه‌ها به صورت embed ذخیره می‌شوند این است که این آیکن برای فایل اجرایی یک برنامه‌ی مدیریت شده هم به کار می‌رود.

فایل‌های اسمبلی Win32 شامل یک فایل مانیفست اطلاعاتی هستند که به طور خودکار توسط کمپایلر سی شارپ تولید می‌گردند. با استفاده از سوئیچ nowin32manifest/ میتوان از ایجاد این نوع فایل جلوگیری کرد. این اطلاعات به طور پیش فرض شبیه زیر است:
<?xml version="1.0" encoding="UTF­8" standalone="yes"?>
<assembly xmlns="urn:schemas­microsoft­com:asm.v1" manifestVersion="1.0">
<assemblyIdentity version="1.0.0.0" name="MyApplication.app" />
<trustInfo xmlns="urn:schemas­microsoft­com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas­microsoft­com:asm.v3">
<requestedExecutionLevel level="asInvoker" uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>
موقعیکه AL یا CSC یک فایل نهایی PE را ایجاد می‌کند، یک منبع نسخه بندی شده با استاندارد win32 نیز به آن Embed می‌شود که با راست کلیک روی فایل و انتخاب گزینه‌ی Properties و برگه‌ی Details این اطلاعات نمایش می‌یابد. در کدنویسی این اپلیکیشن هم می‌توانید از طریق فضای نام system.Diagnostics.FileVersionInfo و متد ایستای آن GetVersionInfo که پارامتر ورودی آن مسیر فایل اسمبلی است هم به این اطلاعات، در حین اجرای برنامه دست پیدا کنید.

موقعیکه شما یک اسمبلی می‌سازید باید فیلدهای منبع نسخه بندی را هم ذکر کنید. اینکار توسط خصوصیت‌ها (Attributes) در سطح کد انجام می‌گیرد. این خصوصیات شامل موارد زیر هستند که در فضای نام Reflection قرار گرفته‌اند.
using System.Reflection;

// FileDescription version information:
[assembly: AssemblyTitle("MultiFileLibrary.dll")]

// Comments version information:
[assembly: AssemblyDescription("This assembly contains MultiFileLibrary's types")]

// CompanyName version information:
[assembly: AssemblyCompany("Wintellect")]

// ProductName version information:
[assembly: AssemblyProduct("Wintellect (R) MultiFileLibrary's Type Library")]

// LegalCopyright version information:
[assembly: AssemblyCopyright("Copyright (c) Wintellect 2013")]

// LegalTrademarks version information:
[assembly:AssemblyTrademark("MultiFileLibrary is a registered trademark of Wintellect")]

// AssemblyVersion version information:
[assembly: AssemblyVersion("3.0.0.0")]

// FILEVERSION/FileVersion version information:
[assembly: AssemblyFileVersion("1.0.0.0")]

// PRODUCTVERSION/ProductVersion version information:
[assembly: AssemblyInformationalVersion("2.0.0.0")]

// Set the Language field (discussed later in the "Culture" section)
[assembly:AssemblyCulture("")]

جدول زیر اطلاعاتی در مورد سوئیچ‌های AL جهت مقداردهی این فیلدهای نسخه بندی دارد (کامپایلر سی شارپ این سوئیچ‌ها را ندارد و بهتر است از طریق همان خصوصیات در کدها اقدام کنید). بعضی از اطلاعات زیر با استفاده از سوئیچ‌ها قابل تغییر نیستند؛ چرا که این مقادیر یا ثابت هستند یا اینکه طبق شرایطی از بین چند مقدار ثابت، یکی از آن‌ها انتخاب می‌شود.

نسخه منبع  سوئیچ AL.exe  توصیف خصوصیت یا سوئیچ مربوطه
 FILEVERSION  fileversion/  System.Reflection.AssemblyFileVersionAttribute.
 PRODUCTVERSION  productversion/  System.Reflection.
AssemblyInformationalVersionAttribute
 FILEFLAGSMASK  -  Always set to VS_FFI_FILEFLAGSMASK (defined in WinVer.h as
0x0000003F).
 FILEFLAGS  - همیشه صفر است
 FILEOS  -  در حال حاضر همیشه VOS__WINDOWS32
است
FILETYPE
target/
Set to VFT_APP if /target:exe or /target:winexe is specified;
set to VFT_DLL if /target:library is specified.

 FILESUBTYPE -

 Always set to VFT2_UNKNOWN. (This field has no meaning for VFT_APP
and VFT_DLL.)
 AssemblyVersion version/  System.Reflection.AssemblyVersionAttribute
 Comments  description/  System.Reflection.AssemblyDescriptionAttribute
 CompanyName  company/  System.Reflection.AssemblyCompanyAttribute
 FileDescription title/  System.Reflection.AssemblyTitleAttribute
 FileVersion  version/  System.Reflection.AssemblyFileVersionAttribute
 InternalName  out/  ذکر نام فایل خروجی بدون پسوند.
 LegalCopyright  copyright/  System.Reflection.AssemblyCopyrightAttribute
 LegalTrademarks  trademark/  System.Reflection.AssemblyTrademarkAttribute
 OriginalFilename  out  ذکر نام فایل خروجی بدون پسوند.
 PrivateBuild  -  همیشه خالی است.
 ProductName  product  System.Reflection.AssemblyProductAttribute
 ProductVersion  productversion  System.Reflection.
AssemblyInformationalVersionAttribute
 SpecialBuild  -  همیشه خالی است.
موقعیکه شما یک پروژه‌ی سی شارپ را ایجاد می‌کنید، فایلی به نام AssebmlyInfo.cs در دایرکتوری Properties پروژه ایجاد می‌شود. این فایل شامل تمامی خصوصیت‌های نسخه بندی که در بالا ذکر شد، به‌علاوه یک سری خصوصیات دیگری که در آینده توضیح خواهیم داد، می‌باشد.
شما برای ویرایش این فایل می‌توانید به راحتی آن را باز کرده و اطلاعات داخل آن را تغییر دهید. ویژوال استودیو نیز برای ویرایش این فایل، امکانات GUI را نیز فراهم کرده است. برای استفاده از این امکان، پنجره‌ی properties را در سطح Solution باز کرده و در تب Application روی Assembly Information کلیک کنید.


اشتراک‌ها
دوره آموزشی چهار ساعته Blazor Hybrid

Learn Blazor Hybrid - Full Course for Beginners | Build cross-platform apps in C#

Let's start our journey together to build beautiful native cross-platform apps for iOS, Android, macOS, and Windows with Blazor Hybrid, .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 Razor, how to show data from the internet, how to navigate between pages and combine .NET MAUI pages with Razor pages, access platform features like geolocation, 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 Blazor Hybrid!

Chapters:

00:00:00 - Intro to the Blazor Hybrid Workshop

00:04:28 - What is Blazor Hybrid & How to Install

00:06:51 - First Blazor Hybrid App & Architecture

00:21:40 - Get Code to Build Your First Blazor Hybrid App

00:26:38 - Blazor Hybrid Project Walkthrough

00:39:22 - Start to Build First Blazor Hybrid App

01:03:10 - Event Handling, Data Binding and Parameters (Slides)

01:09:00 - Add Monkey Data & Fluent UI Blazor Components

01:32:08 - Navigation, NavigationManager, .NET MAUI Pages (Slides)

01:39:19 - Navigation with NavigationManager

01:52:39 - Navigation with NavLinks

01:57:21 - Add .NET MAUI Pages & Components

02:21:11 - Access Platform Functionality (Slides)

02:27:57 - Check Network Connectivity

02:38:04 - Get User Location with Geolocation

02:49:09 - Integration with Other Apps

02:57:42 - App Theming, Light Theme, Dark Theme (Slides)

03:05:36 - JavaScript Interoperability with IJSRuntime

03:20:48 - Theming FluentUI Blazor Components

03:26:05 - Style Status Bar with .NET MAUI Community Toolkit

03:39:00 - .NET MAUI Light & Dark Theme with AppThemeBinding

03:42:58 - Sharing State & Creating Reusable Components (Slides)

03:47:27 - Implement Shared State Blazor Hybrid & .NET MAUI

04:02:47 - Create Reusable Razor Components

04:08:31 - CONGRATULATIONS!

دوره آموزشی چهار ساعته Blazor Hybrid
اشتراک‌ها
کتابخانه jQuery-Responsive-Multi-Level-Menu-Plugin-Dlmenu با افکت های زیبا

An extremely simple and responsive jQuery plugin that allows you to create multi-level drop down menu with subtle effects (sliding, fading, scale up, or scale down).  Each sub-menu in this menu will be shown in its own context, making the “parent” level disappear, good for saving space for menus which have a lot of content

کتابخانه jQuery-Responsive-Multi-Level-Menu-Plugin-Dlmenu با افکت های زیبا
اشتراک‌ها
بررسی میزان پیچیدگی کدها با Microsoft.CodeAnalysis.Metrics

This page describes how to use the Microsoft.CodeAnalysis.Metrics package to perform source code analysis of .NET assemblies from a console application. Visual Studio users can perform source code analysis by clicking the "Analyze" dropdown menu and selecting "Calculate Code Metrics", but I sought to automate this process so I can generate custom code analysis reports from console applications as part of my CI pipeline. 

بررسی میزان پیچیدگی کدها با Microsoft.CodeAnalysis.Metrics
مطالب
ارتباط بین کامپوننت‌ها در Vue.js - قسمت سوم استفاده از تزریق وابستگی‌ها
در قسمت‌های قبلی( ^ و ^) نحوه‌ی ارتباط بین کامپوننت‌ها در Vue.js بررسی و مزایا و معایب آنها بیان شد. روش دیگری هم برای ارسال اطلاعات از کامپوننتِ Parent به فرزندانش وجود دارد که با استفاده از Dependency Injection یا به اختصار DI مقدور می‌باشد و در ورژن +2.2 معرفی شد که نحوه‌ی ارتباط بین کامپوننتِ Parent و فرزندانش را آسان نمود. پیش‌تر برای ارتباط از Parent به Child، از Props استفاده میکردیم، ولی اگر قرار بود در چند سطح این ارتباط عمیق باشد، باز هم مدیریت کردن Props مشکل و سخت بود. اکنون با استفاده از provide و inject قادر خواهیم بود تا آبجکت، فانکشن و یا دیتایِ یک کامپوننتِ Parent را در فرزندانش فراخوانی و استفاده کنیم. اگر در حالت عادی نیاز بود تا در دو سطح، یا بیشتر (مانند تصویر زیر) دیتایِ کامپوننت پدر را به فرزند، نوه و ... انتقال دهیم، می‌بایست اطلاعات را بصورت Props به هر Level انتقال دهیم.



روش جاری شباهت زیادی به استفاده از Context در React دارد:

Context provides a way to pass data through the component tree without having to pass props down manually at every level


جهت به اشتراک گذاری دیتا یا تابعی در کامپوننت Parent با Children، به شکل زیر عمل میکنیم. در اینجا با استفاده از provide، دیتای foo به اشتراک گذاشته شده‌است:
// parent component providing 'foo'
var Provider = {
  provide: {
    foo: 'bar'
  },
  // ...
}
و در کامپوننت‌های فرزند به شکل زیر میتوانیم مقدار foo را دریافت کنیم:
// child component injecting 'foo'
var Child = {
  inject: ['foo'],
  created () {
    console.log(this.foo) // => "bar"
  }
  // ...
}

میتوانیم مقدار پیش فرض دیتایِ ارسالی از کامپوننت Parent را در قسمت data و props در کامپوننت Child دریافت نماییم:
Using an injected value as the default for a prop
//دریافت میکنیم props در قسمت  child را در کامپوننت  foo مقدار
const Child = {
  inject: ['foo'],
  props: {
    bar: {
      default () {
        return this.foo
      }
    }
  }
}

Using an injected value as data entry
//دریافت میکنیم data در قسمت  child را در کامپوننت  foo مقدار
const Child = {
  inject: ['foo'],
  data () {
    return {
      bar: this.foo
    }
  }
}

نکته: در این روش در صورتیکه دیتایِ به اشتراک گذاشته شده در کامپوننتِ Parent تغییر کند، مقدار آن در کامپوننت Child تغییری نخواهد کرد و مانند روش‌های قبلی (^ و ^) نیست و نیاز به نوشتن کدی برای تعامل داشتن و به‌روز رسانی مقادیر، در کامپوننت Child می‌باشد.
کد زیر  را در نظر بگیرید؛ با زدن دکمه‌ی Increment counter  مقدار counter در کامپوننتِParent تغییر میکند، ولی در کامپوننت Child، مقدار counter_in_child  تغییری حاصل نمی‌کند.
<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  <script src="https://cdn.jsdelivr.net/npm/vue"></script>
  <title>Dependency injection</title>
</head>

<body>
  <div id="app">
    <button @click="counter++">Increment counter</button>
    <h2>Parent</h2>
    <p>{{counter}}</p>
    <div>
      <h3>Child</h3>
      <child></child>
    </div>
  </div>
  
<script>
const Child = {
  inject: ['counter_in_child'],
  template: `<div>Counter Child is:{{ counter_in_child }}</div>`
};

new Vue ({
  el: "#app",
  components: { Child },
  provide() {
    return {
      counter_in_child: this.counter
    };
  },
  data() {
    return {
      counter: 0
    };
  }
});
</script>

</body>
</html>
       
برای اینکه بتوان تغییرات ایجاد شده‌ی بر روی دیتا را در کامپوننتِChild، مشاهده کرد، نیاز داریم کد زیر را در قسمت provide به ازای آن دیتا اضافه کنیم: 
<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  <script src="https://cdn.jsdelivr.net/npm/vue"></script>
  <title>Dependency injection</title>
</head>

<body>
  <div id="app">
    <button @click="counter++">Increment counter</button>
    <h2>Parent</h2>
    <p>{{counter}}</p>
    <div>
      <h3>Child</h3>
      <child></child>
    </div>
  </div>
  
<script>
const Child = {
  inject: ['counter_in_child'],
  template: `<div>Counter Child is:{{ counter_in_child.counter }}</div>`
};

new Vue ({
  el: "#app",
  components: { Child },
  provide() {
    const counter_in_child={};
Object.defineProperty(counter_in_child,'counter',{
enumerable:true,
get:()=>this.counter
})
    return {
      counter_in_child
    };
  },
  data() {
    return {
      counter: 0
    };
  }
});
</script>

</body>
</html>

مثالی از نحوه به اشتراک گذاری متد بین Parent و Child.

نتیجه گیری:
A) استفاده از این روش مرسوم نیست و بیشتر برای ساخت پلاگین در Vuejs مورد استفاده قرار میگیرد:
provide  and  inject  are primarily provided for advanced plugin / component library use cases. It is NOT recommended to use them in generic application code
B) برای استفاده از این روش کتابخانه‌هایی جهت ساده‌تر کردن بکارگیری ایجاد شده‌است.
C) این روش برای ارتباط  Sibling Component مناسب نیست.
اشتراک‌ها
روش صحیح استفاده از ASP.NET Identity، بدون وابستگی Domain و سایر لایه ها به آن

The Problem

What they neglect to say is all that testability and persistence ignorance flies right out the window when you create a new ASP.NET Web Application using the MVC template and "Individual User Accounts" authentication. What you get is a single-layered application, tightly coupled to Entity Framework, that:

  • Ignores the patterns that facilitate testing, including: the repository pattern, unit of work pattern, and dependency injection;

  • Forces you to implement their IUser interface in your application’s User entity, thereby coupling it to ASP.NET Identity;

  • Eliminates any clear separation between your entities, persistence concerns, and business logic. Persistence ignorance? Forget about it.

Thankfully, due to the extensibility designed into ASP.NET Identity, it is possible to ditch the reference to the Microsoft.AspNet.Identity.EntityFramework assembly and write a custom implementation that can address these and other architectural issues. Just be forewarned: it is not a trivial undertaking, and you’ll have to put up with some code smell that is baked into the Microsoft.AspNet.Identity.Core assembly. 

روش صحیح استفاده از ASP.NET Identity، بدون وابستگی Domain و سایر لایه ها به آن
اشتراک‌ها
PSScriptAnalyzer (PSSA) 1.21.0 منتشر شد

PSScriptAnalyzer is a static code checker for PowerShell modules and scripts. PSScriptAnalyzer checks the quality of PowerShell code by running a set of rules. The rules are based on PowerShell best practices identified by PowerShell Team and the community. It generates DiagnosticResults (errors and warnings) to inform users about potential code defects and suggests possible solutions for improvements. 

PSScriptAnalyzer (PSSA) 1.21.0 منتشر شد