using System; namespace MyVerboseApp { public class Program { public static void Main(string[] args) { Console.WriteLine("Hello World!"); } } }
// See https://aka.ms/new-console-template for more information Console.WriteLine("Hello, World!");
روش بازگشت به قالبهای قبلی
در حال حاضر و در نگارش فعلی و حتی رسمی دات نت 6، روشی برای بازگشت به حالت قبلی وجود ندارد که به احتمال زیاد در نگارشهای پس از RTM لحاظ خواهد شد (میتوانید در اینجا ^ و ^ به آن رای دهید). تنها راه حل موجود، استفاده از دستور زیر است:
dotnet new console --framework net5.0 --target-framework-override net6.0
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> - <TargetFramework>net5.0</TargetFramework> + <TargetFramework>net6.0</TargetFramework> </PropertyGroup> </Project>
Angular Essentials
این افزونه گروهی از مهمترین افزونههای موجود را به صورت بسته بندی شده ارائه میدهد و با نصب آن، تعدادی از افزونههایی را که در ادامه نامبرده خواهند شد، به صورت یکجا و خودکار دریافت خواهید کرد.
Angular Language Service
نگارشهای اخیر Angular به همراه یک سرویس زبان نیز میباشند که به ادیتورهای مختلف این امکان را میدهد تا توسط این ویژگی بتوانند قابلیتهای ویرایشی بهتری را جهت برنامههای Angular ارائه کنند. برای مثال ویرایش مطلوب قالبهای کامپوننتهای Angular و استفادهی از Syntax خاص آن، موردی است که توسط هیچکدام از HTML ادیتورهای موجود پشتیبانی نمیشود. اکنون به کمک سرویس زبان Angular و افزونهی ویژهی آن برای VSCode که توسط تیم اصلی Angular توسعه یافتهاست، امکان ویرایش غنی قالبهای HTML ایی آن فراهم شدهاست. این افزونه یک چنین قابلیتهایی را فراهم میکند:
الف) AOT Diagnostic messages
اگر قالب HTML ایی مورد استفاده (چه به صورت inline و چه در یک فایل html مجزا) به خاصیتی تعریف نشده اشاره کند، بلافاصله خطای مرتبطی ظاهر خواهد شد:
ب) Completions lists یا همان Intellisense
ج) امکان Go to definition با کلیک راست بر روی خواص و متدهای ذکر شدهی در قالب.
د) Quick info که با نزدیک کردن اشارهگر ماوس به خاصیت یا متدی در صفحه، اطلاعات بیشتری را در مورد آن نمایش میدهد.
angular2-inline
علاوه بر افزونهی سرویس زبانهای Angular، این افزونه نیز قابلیت درک قالبهای inline کامپوننتها را داشته و به همراه syntax highlighting و همچنین Intellisense است.
Auto Import
حین کار با TypeScript، هر ماژولی که در صفحه ارجاعی داشته باشد، باید در ابتدای فایل جاری import شود. افزونهی Auto Import با بررسی ماژولهای موجود و فراهم آوردن Intellisense ایی بر اساس آنها، اینکار را سادهتر میکند:
بنابراین این افزونه صرفا مختص به Angular نیست و برای کارهای متداول TypeScript نیز بسیار مفید است.
TSLint
این افزونه ابزار TSLint را با VSCode یکپارچه میکند. بنابراین نیاز است پیش از نصب این افزونه، وابستگیهای ذیل را نیز به صورت سراسری نصب کرد:
> npm install -g tslint typescript
تعدادی از امکانات آنرا پس از نصب، با فشردن دکمهی F1 میتوان مشاهده کرد:
برای مثال تولید فایل tslint.json، امکان سفارشی سازی موارد بررسی شوندهی توسط این افزونه را فراهم میکند و اگر برنامهی خود را توسط Angular CLI ایجاد کردهاید، این فایل هم اکنون در ریشهی پروژه قرار دارد.
در مورد TSLint در مطلب «Angular CLI - قسمت دوم - ایجاد یک برنامهی جدید» بیشتر توضیح داده شدهاست و اینبار به کمک این افزونه، خطاهای یاد شده را دقیقا درون محیط ادیتور و به صورت خودکار و یکپارچهای مشاهده خواهید کرد.
Angular v4 TypeScript Snippets
سیستم کار VSCode مبتنی بر ایجاد فایلهای خالی است و مفهوم قالبهای از پیش آمادهی فایلها در آن وجود ندارد. اما با کمک Code Snippets میتوان این خلاء را پر کرد. افزونهی Angular v4 TypeScript Snippets دقیقا به همین منظور طراحی شدهاست و زمانیکه حروف -a یا -rx را در صفحه تایپ میکنید، منویی ظاهر خواهد شد که توسط آن میتوان قالب ابتدایی شروع به کار با انواع و اقسام جزئیات پروژههای Angular را تهیه کرد.
Path Intellisense
این افزونه مسیر فایلهای موجود را به صورت یک Intellisense ارائه میکند و به این صورت به سادگی میتوان مسیرهای اسکریپتها و یا شیوهنامهها را در ادیتور انتخاب و وارد کرد.
خطای هم نامی خواص راهبری
بله، در حالت تعریف خواص یک کلاس که قرار است امکان تعریف قالبهای متعددی توسط کاربر را داشته باشد، از اینترفیسها هم ممکن است استفاده شود. در خود PdfReport در بسیاری از موارد از این روش استفاده شده. مثلا تعریف فونت آن یا بسیاری از سفارشی سازیهای دیگر.
اما کار با ORMها یک سری اصول عمومی پذیرفته شده دارد و جهت تعریف خواص تو در توی کلاسهای آن، استفاده از اینترفیسها عمومیت ندارد.
شاید عنوان کنید که DI من کار تزریق وهله مورد نظر رو انجام میده ولی .... خود ORM یک سربار است. DI هم سربار دوم. آیا کارآیی اینجا باید فدای طراحی نادرستی شود؟ استفاده از اینترفیسها الزاما به معنای حرفهای بودن یک طراحی نیست. بستگی داره کجا استفاده شدند. آیا قابلیت سفارشی سازی و افزونه پذیری رو ارائه میکنه؟ یا خیر؟
ویژگیهای C# 10.0
Microsoft's release notes highlights for Preview 3 include:
- Visual Studio now offers .NET Framework 4.7.2 development tools to supported platforms with 4.7.2 runtime included.
- We improved performance during project unload/reload and branch switching.
- With added support for Azure Functions, you now have a new target host in the Configure Continuous Delivery to Azure dialog.
- Git and TFS status now updates properly for external file changes in .NET Core projects.
- We added new productivity features, such as code cleanup, invert-if refactoring, Go to Enclosing Block, Multi-Caret support, and new keyboard profiles.
- C++ enhancements include Template IntelliSense, convert macro to constexpr lightbulbs, and experimental in-editor code analysis squiggles.
- You can now use cross-language debugging with Python 3.7.0rc1.
- Performance Profiling now offers the ability to pause/resume data collection and adds a new .NET Object Allocation Tracking tool.
- We included improvements for Android incremental builds in the Xamarinsupport for Xcode 9.4.
به عنوان مثال:
- New
- Approved
- Committed
- Done
- Removed
در وضعیتهای فوق چنانچه یک Work item اشتباهاً به Backlog افزوده شود، تنها راه اینکه اعلام کنیم این Work item از دستور کار خارج شده است، اینست که آنرا در وضعیت Removed قرار دهیم.
در هیچ کجای رابط کاربری (تحت وب و Team explorer در ویژوال استدیو) امکانی برای حذف یک Work item در نظر گرفته نشده است.
در ادامه روش حذف فیزیکی یک Work item از TFS را خواهیم دید:
1- ابتدا وارد خط فرمان (Command Prompt) شده و به مسیر زیر بروید:
cd %programfiles(x86)%\Microsoft Visual Studio 12.0\Common7\IDE
witadmin destroywi /collection:CollectionURL /id:id
witadmin destroywi /collection:"https://mytfs.visualstudio.com/DefaultCollection " /id:357
چنانچه این قابلیت نظر شما را جلب کرد، توصیه میکنم نگاهی هم به سایر سوییچهای فرمان witadmin بیاندازید.
معماری میکرو سرویس یا یکپارچه؟
برای درک میکروسرویسها، باید بدانیم کاربرد سیستمهای یکپارچه چیست و چه چیزی باعث شد در زمانهای اخیر از برنامههای یکپارچه به میکروسرویسها حرکت کنیم.
سیستمهای یکپارچه ( Monolithic applications )
اگر تمام عملکردهای یک پروژه در یک بخش واحد وجود داشته باشند، آن برنامه به عنوان یک برنامهی یکپارچه شناخته میشود. ما برنامهی خود را در لایههای مختلفی مانند Presentation ، Service ، UI طراحی میکنیم و سپس آن بخش از کدهای نوشته شده را به عنوان یک فایل خروجی به کار میگیریم. این چیزی نیست جز یک برنامهی یکپارچه، که در آن " mono " یک پایگاه کد منفرد حاوی تمام عملکردهای مورد نیاز را نشان میدهد.
چرا اصلا به سمت میکروسرویسها برویم؟
خب برای جواب به این سوال بهتر است معایب سیستمهای یکپارچه را مرور کنیم:
- مدیریت دشوار بخاطر گسترش برنامه در گذشت زمان
- برای تغییری کوچک، کل برنامه را دوباره باید منتشر ( publish ) کنیم
- با تغییر و آپدیت برنامه، زمان انتشار افزایش مییابد.
- درک دشوار برای توسعه دهندههای جدید هر پروژه
- برای تقسیم ترافیک روی قسمتهای مختلف برنامه، باید نمونههای کل برنامه را در چندین سرور منتشر کنیم که بسیار ناکارآمد و باعث استفادهی بیهوده از منابع میشود
- اگر از فناوری یا تکنولوژیهای جدید استفاده کنیم، برای عملکردی خاص، چه از نظر هزینه و چه از نظر زمان، بر کل برنامه تاثیر گذار است
- و در نهایت وجود یک باگ در هر ماژول میتواند کل برنامه را مختل کند.
و اما مزایای سیستمهای یکپارچه:
- توسعهی آن نسبت به میکروسرویسها ساده است.
- انتشار آن آسانتر است؛ زیرا فقط یک خروجی، مستقر شدهاست.
- در مقایسه با معماری میکروسرویسها، توسعهی آن نسبتا آسانتر و سادهتر است.
- مشکلات تأخیر و امنیت شبکه در مقایسه با معماری میکروسرویسها نسبتاً کمتر است.
- توسعه دهندگان نیازی به یادگیری برنامههای مختلف ندارند؛ آنها میتوانند تمرکز خود را بر روی یک برنامه حفظ کنند.
میکروسرویس ها
این یک سبک توسعه معماری است که در آن برنامه از سرویسهای کوچکتری تشکیل شدهاست که بخش کوچکی از عملکرد و دادهها را با برقراری ارتباط مستقیم با یکدیگر، با استفاده از پروتکلی مانند HTTP مدیریت میکند. به عبارتی دیگر خدمات یا سرویسهای کوچکی هستند که با هم کار میکنند.
معماری میکروسرویس تأثیر بسزایی در رابطهی بین برنامه و پایگاه داده دارد. بجای اشتراک گذاری یک پایگاه داده با سایر میکروسرویسها، هر میکروسرویس، پایگاه داده خاص خود را دارد که اغلب منجر به تکثیر برخی از دادهها میشود، اما اگر میخواهید از این معماری بهره مند شوید، داشتن یک پایگاه داده در هر میکروسرویس، ضروری است؛ زیرا اتصال ضعیف را تضمین میکند. مزیت دیگر داشتن یک پایگاه دادهی مجزا برای هر میکروسرویس این است که هر میکروسرویس میتواند از نوع پایگاه دادهای که برای نیازهای خود مناسبتر است، استفاده کند. هر سرویس یک ماژول را ارائه میدهد، به طوری که خدمات مختلف را میتوان به زبانهای برنامه نویسی مختلف نوشت. الگوهای زیادی در معماری میکروسرویس دخیل هستند مانند discovery و registry service ، Caching ، ارتباط API ، امنیت و غیره.
اصول میکروسرویسها:
تک مسئولیتی: یکی از اصولی است که به عنوان بخشی از الگوی طراحی SOLID تعریف شده است. بیان میکند که یک Unit ، یا یک کلاس، یک متد یا یک میکروسرویس باید تنها یک مسئولیت را داشته باشد. هر میکروسرویس باید یک مسئولیت داشته باشد و یک عملکرد واحد را ارائه دهد. شما همچنین میتوانید بگویید تعداد میکروسرویسهایی که باید توسعه دهید، برابر با تعداد عملکردهای مورد نیاز شما است. پایگاه داده نیز غیرمتمرکز است و به طور کلی، هر میکروسرویس، پایگاه داده خاص خود را دارد.
بر اساس قابلیتهای تجاری ساخته شده است: در دنیای امروزی که فناوریهای زیادی وجود دارند، همیشه فناوریای وجود دارد که برای اجرای یک عملکرد خاص مناسبتر است. اما در برنامههای یکپارچه، این یک اشکال بزرگ بود؛ زیرا ما نمیتوانیم از فناوریهای مختلف برای هر عملکرد استفاده کنیم و از این رو، نیاز به مصالحه در زمینههای خاص داریم. یک میکروسرویس هرگز نباید خود را از پذیرش پشته فناوری مناسب یا ذخیرهسازی پایگاه داده پشتیبان که برای حل هدف تجاری مناسبتر است، محدود کند؛ بهعنوان مثال، هر میکروسرویس میتواند بر اساس نیازهای تجاری از فناوریهای متفاوتی استفاده کند.
طراحی برای مدیریت خطاها: میکروسرویسها باید با در نظر گرفتن مدیریت خطاها طراحی شوند. میکروسرویسها باید از مزیت این معماری استفاده کنند و پایین آمدن یک میکروسرویس نباید بر کل سیستم تأثیر بگذارد و سایر عملکردها باید در دسترس کاربر باقی بمانند. اما در برنامههای کاربردی سیستمهای یکپارچه که خطای یک ماژول منجر به سقوط کل برنامه میشود، اینگونه نبود.
مزایای میکروسرویس ها:
- مدیریت آن آسان است زیرا نسبتا کوچکتر است.
- اگر در یکی از میکروسرویسها، بروزرسانی وجود داشته باشد، باید فقط آن میکروسرویس را مجدداً منتشر کنیم.
- میکروسرویسها مستقل هستند و از این رو به طور مستقل منتشر میشوند. زمان راه اندازی و انتشار آنها نسبتاً کمتر است.
- برای یک توسعهدهنده جدید بسیار آسان است که وارد پروژه شود، زیرا او باید فقط یک میکروسرویس خاص را که عملکردی را که روی آن کار میکند، درک کند و نه کل سیستم را.
- اگر یک میکروسرویس خاص به دلیل استفاده بیش از حد کاربران از آن عملکرد، با بار زیادی مواجه است، ما باید فقط آن میکروسرویس را تنظیم کنیم. از این رو، معماری میکروسرویس از مقیاس بندی افقی پشتیبانی میکند.
- هر میکروسرویس بر اساس نیازهای تجاری میتواند از فناوریهای مختلفی استفاده کند.
- اگر یک میکروسرویس خاص به دلیل برخی باگها از کار بیفتد، بر روی سایر میکروسرویسها تأثیر نمیگذارد و کل سیستم دست نخورده باقی میماند و به ارائه سایر عملکردها به کاربران ادامه میدهد.
معایب میکروسرویس ها:
- پیچیده است و پیچیدگی آن با افزایش تعداد ریز سرویسها افزایش مییابد.
- نیاز به نیروهای متخصص
- استقرار مستقل میکروسرویسها پیچیدهاست.
- میکروسرویسها از نظر استفاده از شبکه پرهزینه هستند؛ زیرا نیاز به تعامل با یکدیگر دارند و همه این تماسهای راه دور منجر به تأخیر شبکه میشود.
- امنیت کمتر به دلیل ارتباط بین سرویسها
- اشکال زدایی دشوار است
مثالی از کاربرد واژهی dynamic جهت جایگزین کردن آن با DTOs
OVER ( [ <PARTITION BY clause> ] [ <ORDER BY clause> ] [ <ROW or RANGE clause> ] ) <PARTITION BY clause> ::= PARTITION BY value_expression , ... [ n ] <ORDER BY clause> ::= ORDER BY order_by_expression [ COLLATE collation_name ] [ ASC | DESC ] [ ,...n ] <ROW or RANGE clause> ::= { ROWS | RANGE } <window frame extent> <window frame extent> ::= { <window frame preceding> | <window frame between> } <window frame between> ::= BETWEEN <window frame bound> AND <window frame bound> <window frame bound> ::= { <window frame preceding> | <window frame following> } <window frame preceding> ::= { UNBOUNDED PRECEDING | <unsigned_value_specification> PRECEDING | CURRENT ROW } <window frame following> ::= { UNBOUNDED FOLLOWING | <unsigned_value_specification> FOLLOWING | CURRENT ROW } <unsigned value specification> ::= { <unsigned integer literal> }
CREATE TABLE REVENUE ( [DepartmentID] int, [Revenue] int, [Year] int ); insert into REVENUE values (1,10030,1998),(2,20000,1998),(3,40000,1998), (1,20000,1999),(2,60000,1999),(3,50000,1999), (1,40000,2000),(2,40000,2000),(3,60000,2000), (1,30000,2001),(2,30000,2001),(3,70000,2001)
select *, avg(Revenue) OVER (PARTITION by DepartmentID) as AverageRevenue, sum(Revenue) OVER (PARTITION by DepartmentID) as TotalRevenue from REVENUE order by departmentID, year;
insert into REVENUE values(1,90000,2002),(2,20000,2002),(3,80000,2002), (1,10300,2003),(2,1000,2003), (3,90000,2003), (1,10000,2004),(2,10000,2004),(3,10000,2004), (1,20000,2005),(2,20000,2005),(3,20000,2005), (1,40000,2006),(2,30000,2006),(3,30000,2006), (1,70000,2007),(2,40000,2007),(3,40000,2007), (1,50000,2008),(2,50000,2008),(3,50000,2008), (1,20000,2009),(2,60000,2009),(3,60000,2009), (1,30000,2010),(2,70000,2010),(3,70000,2010), (1,80000,2011),(2,80000,2011),(3,80000,2011), (1,10000,2012),(2,90000,2012),(3,90000,2012)
select Year, DepartmentID, Revenue, sum(Revenue) OVER (PARTITION by DepartmentID ORDER BY [YEAR] ROWS BETWEEN 3 PRECEDING AND CURRENT ROW) as Prev3 From REVENUE order by departmentID, year;
ROWS BETWEEN 3 PRECEDING AND CURRENT ROW) as Prev3
select Year, DepartmentID, Revenue, sum(Revenue) OVER (PARTITION by DepartmentID ORDER BY [YEAR] ROWS BETWEEN CURRENT ROW AND 3 FOLLOWING) as Next3 From REVENUE order by departmentID, year;
select Year, DepartmentID, Revenue, min(Revenue) OVER (PARTITION by DepartmentID ORDER BY [YEAR] ROWS UNBOUNDED PRECEDING) as MinRevenueToDate From REVENUE order by departmentID, year;
RANGE UNBOUNDED PRECEDING AND CURRENT ROW
CREATE TABLE Employees ( EmployeeId INT IDENTITY PRIMARY KEY, Name VARCHAR(50), HireDate DATE NOT NULL, Salary INT NOT NULL ) GO INSERT INTO Employees (Name, HireDate, Salary) VALUES ('Alice', '2011-01-01', 20000), ('Brent', '2011-01-15', 19000), ('Carlos', '2011-02-01', 22000), ('Donna', '2011-03-01', 25000), ('Evan', '2011-04-01', 18500) GO
SELECT Name, Salary, AVG(Salary) OVER(ORDER BY HireDate) AS avgSalary FROM Employees GO
SELECT Name, Salary, AVG(Salary) OVER(ORDER BY HireDate RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS avgSalary FROM Employees GO
SELECT Name, Salary, AVG(Salary) OVER(ORDER BY HireDate RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) AS avgSalary FROM Employees GO