Below is an illustration of how diffing works in Blazor (which copies React component model almost exactly):
به روز رسانی وابستگیهای VS.NET
برای دریافت آخرین نگارش TypeScript نیاز است افزونههای آنرا از سایت رسمی زبان TypeScript دریافت و نصب کرد:
به علاوه نصب افزونهی Web Essentials نیز جهت تکمیل امکانات کار با TypeScript مانند امکان مشاهدهی خروجی جاوا اسکریپت تولیدی، در حین کار با فایل TypeScript فعلی توصیه میشود. همچنین TSLint را نیز نصب میکند.
افزودن فایل تنظیمات tslint
افزونهی Web Essentials که Web Analyzer نیز اکنون جزئی از آن است، به همراه TSLint هم هست که کار آن ارائه راهنماهایی جهت تولید کدهای با کیفیت TypeScript است. گزینههای آنرا در منوی Tools -> Options میتوانید مشاهده کنید:
برای بازنویسی تنظیمات آن (در صورت نیاز) فایل جدیدی را به نام tslint.json به ریشهی پروژه (کنار فایل web.config) اضافه کنید. فایل پیش فرض آن چنین شکلی را دارد:
settings-defaults/tslint.json
و یک نمونهی اصلاح شدهی آن به صورت ذیل است که میتواند به ریشهی پروژه کپی شود:
tslint.json
تنظیمات کامپایلر TypeScript در VS.NET
هرچند قالب افزودن یک پروژهی جدید TypeScript نیز به همراه نصب بستههای TypeScript به لیست پروژههای موجود اضافه میشود، اما عموما نیاز است تا فایلهای ts. را به یک پروژهی وب موجود اضافه کرد. بنابراین، یک پوشهی جدید را به برای مثال به نام TypeScript ایجاد کرده و بر روی آن کلیک راست کنید. سپس گزینهی Add->new item را انتخاب کرده و در اینجا TypeScript را جستجو کنید:
پس از اضافه شدن اولین فایل ts. به پروژه، دیالوگ زیر نیز ظاهر خواهد شد:
در اینجا جستجوی فایلهای d.ts. را پیشنهاد میدهد. فعلا بر روی No کلیک کنید. اینکار را در ادامه انجام خواهیم داد.
پس از افزودن اولین فایل ts. به پروژه، اگر به خواص پروژهی جاری مراجعه کنید، برگهی جدید تنظیمات کامپایلر TypeScript را مشاهده خواهید کرد:
با این تنظیمات در مطلب «تنظیمات کامپایلر TypeScript» پیشتر آشنا شدهاید. برای مثال فرمت خروجی جاوا اسکریپت آن ES 5 باشد و یا در اینجا نوعهای any که به صورت صریح any تعریف نشدهاند، ممنوع شدهاست (تیک پیش فرض آنرا بردارید). نوع ماژولهای تولیدی نیز به commonjs تنظیم شدهاست.
همچنین در اینجا میتوانید گزینهی redirect JavaScript output to directory را هم مثلا به پوشهی Scripts واقع در ریشهی پروژه تنظیم کنید تا فایلهای js. نهایی را در آنجا قرار دهد.
پس از این تنظیمات اولیه، به منوی tools->options مراجعه کرده و گزینهی کامپایل فایلهای ts. ایی را که به solution explorer اضافه نشدهاند، نیز فعال کنید:
اعمال این تنظیمات نیاز به یکبار بستن و گشودن مجدد پروژه را دارد.
فعال سازی کامپایل خودکار فایلهای ts. پس از ذخیرهی آنها
پس از اعمال تغییرات فوق، اگر فایل ts. ایی را تغییر داده و ذخیره کردید و بلافاصله خروجی js. آنرا مشاهده نکردید (این فایلها در پوشهی TypeScriptOutDir تنظیمات ذیل ذخیره میشوند و برای مشاهدهی آنها باید گزینهی show all files را در solution explorer فعال کنید)، فایل csproj پروژهی جاری را در یک ادیتور متنی باز کرده و مداخل تنظیمات تنظیم شدهی در قسمت قبل را پیدا کنید. در اینجا نیاز است مدخل جدید TypeScriptCompileOnSaveEnabled را به صورت دستی اضافه کنید:
<PropertyGroup Condition="'$(Configuration)' == 'Debug'"> <TypeScriptModuleKind>commonjs</TypeScriptModuleKind> <TypeScriptCompileOnSaveEnabled>True</TypeScriptCompileOnSaveEnabled> <TypeScriptOutDir>.\Scripts</TypeScriptOutDir> <TypeScriptNoImplicitAny>True</TypeScriptNoImplicitAny> <TypeScriptTarget>ES5</TypeScriptTarget> <TypeScriptRemoveComments>false</TypeScriptRemoveComments> <TypeScriptOutFile></TypeScriptOutFile> <TypeScriptGeneratesDeclarations>false</TypeScriptGeneratesDeclarations> <TypeScriptSourceMap>true</TypeScriptSourceMap> <TypeScriptMapRoot></TypeScriptMapRoot> <TypeScriptSourceRoot></TypeScriptSourceRoot> <TypeScriptNoEmitOnError>true</TypeScriptNoEmitOnError> </PropertyGroup>
رفع مشکل عدم کامپایل پروژه
زمانیکه افزونههای TypeScript را نصب کنید و تنظیمات فوق را اعمال نمائید، در دو حالت ذخیرهی یک فایل ts و یا کامپایل کل پروژه، فایلهای js تولید خواهند شد. اما ممکن است نگارش نصب شدهی بر روی سیستم شما ناقص باشد و چنین خطایی را در حین کامپایل پروژه دریافت کنید:
Your project file uses a different version of the TypeScript compiler and tools than is currently installed on this machine. No compiler was found at C:\Program Files (x86)\Microsoft SDKs\TypeScript\1.8\tsc.exe. You may be able to fix this problem by changing the <TypeScriptToolsVersion> element in your project file.
الف) ابتدا به تمام مسیرهای ذیل (در صورت وجود) مراجعه کرده و پوشهی TypeScript را تغییر نام دهید (یا کلا آنرا حذف کنید):
C:\Program Files (x86)\Microsoft SDKs C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v11.0\ C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v12.0\ C:\Program Files (x86)\MSBuild\Microsoft\VisualStudio\v14.0\
اصلاح شماره نگارش کامپایلر TypeScript خط فرمان ویژوال استودیو
در فایل C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Tools\VsDevCmd.bat که مربوط به خط فرمان VS.NET است، شماره نگارش TypeScript به 1.5 تنظیم شدهاست که نیاز به اصلاح دستی دارد؛ برای مثال تنظیم آن به نگارش 1.8 به صورت زیر است:
@rem Add path to TypeScript Compiler @if exist "%ProgramFiles%\Microsoft SDKs\TypeScript\1.8" set PATH=%ProgramFiles%\Microsoft SDKs\TypeScript\1.8;%PATH% @if exist "%ProgramFiles(x86)%\Microsoft SDKs\TypeScript\1.8" set PATH=%ProgramFiles(x86)%\Microsoft SDKs\TypeScript\1.8;%PATH%
تداخل ReSharper با شماره نگارش TypeScript نصب شده
برای نمونه اگر بخواهیم از decorators استفاده کنیم، یک چنین خطایی نمایش داده میشود:
هرچند در ابتدای بحث، آخرین نگارش TypeScript برای دریافت معرفی شدهاست، اما پس از نصب آن، ممکن است هنوز خطای استفاده از نگارش قدیمی 1.4 را مشاهده کنید. علت آن به نصب بودن ReSharper بر میگردد:
به منوی ReSharper و سپس گزینهی Options آن مراجعه کنید.
ReSharper -> Options -> Code Editing -> TypeScript -> Inspections -> Typescript language level
در اینجا میتوان نگارش TypeScript مورد استفاده را تغییر داد. این شمارهها، نگارشهایی هستند که ReSharper از آنها پشتیبانی میکند و نه شمارهای که نصب شدهاست.
و یا حتی میتوان به صورت کامل فایلهای ts را از کنترل ReSharper خارج کرد:
Tools -> Options -> ReSharper Options -> Code Inspection -> Settings -> File Masks to Skip -> add *.ts
افزودن فایل tsconfig.json به پروژه
همانطور که در مطلب «تنظیمات کامپایلر TypeScript» نیز مطالعه کردید، روش دیگری نیز برای ذکر تنظیمات ویژهی کامپایلر، خصوصا مواردی که در برگهی خواص پروژه هنوز اضافه نشدهاند، با استفاده از افزودن فایل ویژهی tsconfig.json وجود دارد.
پشتیبانی کاملی از فایلهای tsconfig.json در پروژههای VS 2015 با ASP.Core 1.0 وجود دارد و حتی گزینهای در منوی add->new item برای آن درنظر گرفته شدهاست.
اگر گزینهی فوق را در لیست موارد add->new item پیدا نمیکنید (تحت عنوان TypeScript JSON Configuration File)، مهم نیست. تنها کافی است فایل جدیدی را به نام tsconfig.json به ریشهی پوشهی فایلهای ts خود اضافه کنید؛ با این محتوا:
{ "compilerOptions": { "target": "es5", "outDir": "../Scripts", "module": "commonjs", "sourceMap": true, //"watch": true, // JsErrorScriptException (0x30001) //"compileOnSave": true, // https://github.com/Microsoft/TypeScript/issues/7362#issuecomment-196586037 "experimentalDecorators": true, "emitDecoratorMetadata": true } }
در اینجا نیازی به استفاده از گزینهی watch نیست و ممکن است سبب بروز خطای JsErrorScriptException (0x30001) شود. قرار است این مشکل در نگارشهای بعدی افزونهی TypeScript مخصوص VS.NET برطرف شود.
افزودن فایلهای d.ts. از طریق نیوگت
به ازای هر کتابخانهی جاوا اسکریپتی معروف، یک بستهی نیوگت تعاریف نوعهای TypeScript آن هم وجود دارد.
یک مثال: فرض کنید میخواهیم فایل d.ts. کتابخانهی jQuery را اضافه کنیم. برای این منظور jquery.typescript را در بین بستههای نیوگت موجود، جستجو کنید:
برای سایر کتابخانهها نیز به همین صورت است. نام کتابخانه را به همراه typescript جستجو کنید.
.NET 7 minimal API from scratch | FULL COURSE | clean architecture, repository pattern, CQRS MediatR
In this course I want to provide you a project structure and code organization to get you started with real .NET 7 minimal API projects. It's a full course on this topic where I start from creating and explaining the project structure, setting up different layers using EF Core, repository pattern, CQRS and MediatR. The biggest part of the video is however around the .NET 7 minimal API, taking you from the initial setup, explaining route handlers, implementing all CRUD operations and so on. Last but not least, this course walks you through the process of refactoring the .NET 7 minimal API so that it becomes readable, maintainable and scalable. At the end, you'll have a full project structure organized according to modern architectural patterns that you can take as a template for your own projects.
Contents
1. Intro: 00:00
2. Structuring the solution: 01:00
3. Coding the domain layer: 05:25
4. Coding the data access layer: 08:22
5. Creating repositories: 11:17
6. Adding migrations and database update: 22:30
7. CQRS with MediatR: 29:07
8. Route and rout handlers: 52:06
9. Dependency injection: 55:52
10. Implementing GET by ID : 57:40
11. Implementing POST route: 01:00:26
12. Implementing GET all route: 01:03:41
13. Implement PUT and DELETE: 01:04:57
14. Testing with Postman: 01:09:01
15. Is there a problem? 01:12:41
16. Refactoring service registrations: 01:15:49
17. Refactoring route registrations: 01:20:01
18. Automatic registration of endpoints: 01:26:28
19. Introducing route groups: 01:31:43
20. Extract lambdas into instance methods: 01:34:31
21: Model validation with endpoint filters: 01:45:58
22. Global exception handling: 01:55:10
23. Conclusions: 01:59:49
مجموعه نکاتی از VS Code
یک نکتهی تکمیلی: نحوهی نامگذاری ویژهی عناصر در فرمهای جدید Blazor SSR
اگر با نگارشهای دیگر Blazor کار کرده باشید، عموما یک EditForm را به صفحه اضافه کرده و چند المان را به آن اضافه میکنیم و ... کار میکند. حتی اگر کامپوننتهای سفارشی را هم بر این مبنا تهیه کنیم ... بازهم بدون نکتهی خاصی کار میکنند. اما ... در برنامههای Blazor SSR اینطور نیست! زمانیکه برای مثال مدل فرم را به این صورت تعریف میکنیم:
[SupplyParameterFromForm] public OrderPlace? MyModel { get; set; }
و آنرا به نحو متداولی در صفحه نمایش میدهیم:
<InputText @bind-Value="MyModel.City"/>
اگر به المان رندر شدهی در مرورگر مراجعه کنیم، ویژگی name حاصل، با MyModel.City مقدار دهی شدهاست و ... این موضوع درج نام خاصیت مدل (و یا اصطلاحا Html Field Prefix)، برای Blazor SSR بسیار مهم است! تاحدی که اگر از آن آگاه نباشید، ممکن است ساعتی را مشغول دیباگ برنامه شوید که چرا، مقدار نالی را دریافت کردهاید و یا عناصر تعریف شدهی در کامپوننتهای سفارشی، کار نمیکنند و مقدار نمیگیرند!
متاسفانه API بازگشت نام کامل عناصری که توسط Blazor SSR تولید میشود، عمومی نیست و internal است. اگر از کامپوننتهای استاندارد خود Blazor استفاده میکنید، نیازی نیست تا به این موضوع فکر کنید و مدیریت آن خودکار است؛ اما همینکه قصد تولید کامپوننتهای سفارشی مخصوص SSR را داشته باشید، اولین مشکلی را که با آن مواجه خواهید شد، دقیقا همین مسالهی تولید صحیح HtmlFieldPrefixها است.
برای رفع این مشکل و دسترسی به API پشت صحنهی تولید نام فیلدها در Blazor SSR، میتوان از کامپوننت پایهی InputBase خود Blazor ارثبری کرد و به این ترتیب به خاصیت جدید NameAttributeValue آن دسترسی یافت (این خاصیت به داتنت 8 و مخصوص Blazor SSR، اضافه شدهاست) که اینکار در کلاس BlazorHtmlField انجام شدهاست. روش استفادهی از آن هم به صورت زیر است:
private BlazorHtmlField<T?> ValueField => new(ValueExpression ?? throw new InvalidOperationException(message: "Please use @bind-Value here.")); [Parameter] public T? Value { set; get; } [Parameter] public EventCallback<T?> ValueChanged { get; set; } [Parameter] public Expression<Func<T?>> ValueExpression { get; set; } = default!;
زمانیکه میخواهیم در یک کامپوننت سفارشی، خاصیتی bind پذیر را طراحی کنیم، روش کار آن، مانند مثال فوق است که به همراه یک خاصیت، یک EventCallback و یک Expression است تا اعتبارسنجی و انقیاد دوطرفه را فعال کند. اما ... اگر همین Value را مستقیما در فیلدهای کامپوننت استفاده کنیم ... مقدار نمیگیرد؛ چون به همراه نام کامل خاصیت بایند شدهی به آن نیست. برای مثال بجای MyModel.City فقط City درج میشود (که به علت نداشتن .MyModel، سیستم binding از مقدار آن صرفنظر میکند). اکنون با استفاده از BlazorHtmlField فوق، میتوان به نام کامل تولیدی توسط Blazor SSR دسترسی یافت و از آن استفاده کرد:
<input type="text" dir="ltr" name="@ValueField.HtmlFieldName" id="@ValueField.HtmlFieldName" />
HtmlFieldName ای که در اینجا درج میشود، توسط خود Blazor محاسبه شده و با انتظارات موتور binding آن تطابق دارد و دیگر به خواص بایند شدهای که مقدار نمیگیرند، نخواهیم رسید.
The desktop is here to stay. Sam Basu reviews how you can take advantage of the latest in .NET technologies and still build the apps your customers demand.
Sam covers Windows Forms, XAML (UWP,
WinUI), Progressive Web Apps, Electron, Blazor Mobile Bindings, .NET
MAUI and building for Mac OS and Linux.