مشخصات بستههای خوب NPM در سال 2021
معرفی NET 5 Preview 4.
.NET apps can now run natively on Windows ARM64. This follows the support we added for Linux ARM64 in .NET Core 3.0. With .NET 5.0, you can develop web and UI apps on Windows ARM64 devices, and deliver your applications to users who own Surface Pro X and similar devices. You can already run .NET Core and .NET Framework apps on Windows ARM64, but via x86 emulation. It’s workable, but native ARM64 execution has much better performance.
روش تعریف خواص سفارشی MSBuild در پروژهی Source Generator
در مثال همین سری، به پوشهی NotifyPropertyChangedGenerator مراجعه کرده و فایل جدید NotifyPropertyChangedGenerator.props را با محتوای زیر به آن اضافه میکنیم:
<Project> <ItemGroup> <CompilerVisibleProperty Include="SourceGenerator_CustomRootNamespace"/> </ItemGroup> </Project>
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <GeneratePackageOnBuild>true</GeneratePackageOnBuild> <!-- Generates a package at build --> <IncludeBuildOutput>false</IncludeBuildOutput> <!-- Do not include the generator as a lib dependency --> </PropertyGroup> <ItemGroup> <!-- Package the generator in the analyzer directory of the nuget package --> <None Include="$(OutputPath)\$(AssemblyName).dll" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false"/> <!-- Package the props file --> <None Include="NotifyPropertyChangedGenerator.props" Pack="true" PackagePath="build" Visible="true"/> </ItemGroup> </Project>
یک نکتهی مهم! اگر بخواهیم مستقیما از پروژهی source generator خود مثلا در پروژهی NotifyPropertyChangedGenerator.Demo این سری همانند قبل استفاده کنیم، تنظیمات ذکر شدهی در فایل props. فوق، در آن قابل دسترسی نخواهند بود و با پروسهی build یکی نمیشوند. تنظیماتی که تا اینجا ذکر شدند، فقط مخصوص بستهی نیوگت نهایی است. برای استفادهی مستقیم از آنها در پروژهی Demo، نیاز است یکبار دیگر محتویات props. تولید کنندهی کد را داخل فایل csproj. پروژهی Demo، تعریف کرد. یا میتوان از روش استفاده از فایل ویژهی Directory.Build.props و قابلیتهای ارثبری آن استفاده کرد. یعنی یک فایل Directory.Build.props را در بالاترین سطح ممکن قرار داد و CompilerVisiblePropertyها را در آن تعریف کرد تا در تمام پروژههای برنامه قابل دسترسی شوند.
روش تعریف خواص سفارشی MSBuild در پروژهی استفاده کننده از Source Generator
در مثال این سری چون از بستهی نیوگت تولید کنندهی کد استفاده نمیکنیم، نیاز است خاصیت سفارشی تعریف شده را یکبار دیگر داخل فایل csproj. پروژهی Demo تعریف کنیم. پس از آن میتوان این خاصیت را در قسمت PropertyGroup مقدار دهی کرد:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <SourceGenerator_CustomRootNamespace>ThisIsTest</SourceGenerator_CustomRootNamespace> </PropertyGroup> <ItemGroup> <CompilerVisibleProperty Include="SourceGenerator_CustomRootNamespace"/> </ItemGroup> </Project>
روش دسترسی به مقدار خاصیت سفارشی MSBuild در پروژهی Source Generator
پس از این مقدمات، خواص عمومی MSBuild از طریق خاصیت AnalyzerConfigOptions.GlobalOptions و متد TryGetValue آن با فرمول زیر قابل دسترسی هستند. قسمت build_property ثابت بوده و جزو موارد توکار MSBuild است:
internal static class SourceGeneratorContextExtensions { public static string GetMSBuildProperty( this GeneratorExecutionContext context, string property, string defaultValue = "") { return !context.AnalyzerConfigOptions.GlobalOptions.TryGetValue($"build_property.{property}", out var value) ? defaultValue : value; } }
[Generator] public class NotifyPropertyChangedGenerator : ISourceGenerator { public void Initialize(GeneratorInitializationContext context) { } public void Execute(GeneratorExecutionContext context) { var customRootNamespace = context.GetMSBuildProperty("SourceGenerator_CustomRootNamespace", "Test");
معرفی خاصیت ویژهی AdditionalFiles
تا اینجا روش تعریف یک خاصیت جدید MSBuild و روش دسترسی به آنرا بررسی کردیم. خاصیت توکاری به نام AdditionalFiles نیز در MSBuild تعریف شدهاست که در پروژههای Source Generator جهت دسترسی به فایلها و محتوای آنها قابل استفاده است. برای نمونه میتوان در فایل csproj. پروژهی Demo تعریف زیر را ارائه کرد:
<Project Sdk="Microsoft.NET.Sdk"> <ItemGroup> <AdditionalFiles Include="file1.txt" Visible="false"/> </ItemGroup> </Project>
خاصیت Visible در اینجا مشخص میکند که آیا file1.txt در IDE، در کنار لیست سایر فایلها نمایش داده شود یا خیر.
امکان تعریف خواص سفارشی بر روی AdditionalFiles
فرض کنید علاقمندیم خاصیت ویژهای را به AdditionalFiles اضافه کنیم؛ برای مثال به نام SourceGenerator_EnableLogging مانند مثال زیر:
<Project Sdk="Microsoft.NET.Sdk"> <ItemGroup> <AdditionalFiles Include="file2.txt" SourceGenerator_EnableLogging="true" Visible="false"/> </ItemGroup> </Project>
الف) فایل NotifyPropertyChangedGenerator.props تعریف شده را به صورت زیر تکمیل میکنیم:
<Project> <ItemGroup> <CompilerVisibleProperty Include="SourceGenerator_CustomRootNamespace"/> <CompilerVisibleProperty Include="SourceGenerator_EnableLogging"/> <CompilerVisibleItemMetadata Include="AdditionalFiles" MetadataName="SourceGenerator_EnableLogging"/> </ItemGroup> </Project>
ب) در فایل csproj. پروژهی Demo، از این خواص و متادیتاها استفاده میکنیم:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <SourceGenerator_EnableLogging>true</SourceGenerator_EnableLogging> </PropertyGroup> <ItemGroup> <CompilerVisibleProperty Include="SourceGenerator_EnableLogging"/> <CompilerVisibleItemMetadata Include="AdditionalFiles" MetadataName="SourceGenerator_EnableLogging"/> <AdditionalFiles Include="file1.txt" Visible="false"/> <!-- logging will be controlled by default, or global value --> <AdditionalFiles Include="file2.txt" SourceGenerator_EnableLogging="true" Visible="false"/> <!-- always enable logging for this file --> <AdditionalFiles Include="file3.txt" SourceGenerator_EnableLogging="false" Visible="false"/> <!-- never enable logging for this file --> </ItemGroup> </Project>
ج) برای خواندن این خواص در پروژهی Source generator به صورت زیر عمل میشود:
internal static class SourceGeneratorContextExtensions { public static string GetAdditionalFilesOption( this GeneratorExecutionContext context, AdditionalText additionalText, string property, string defaultValue = "") { return !context.AnalyzerConfigOptions.GetOptions(additionalText) .TryGetValue($"build_metadata.AdditionalFiles.{property}", out var value) ? defaultValue : value; } }
- روش تامین AdditionalText این متد را نیز در مثال زیر مشاهده میکنید که حاصل ایجاد حلقهای بر روی context.AdditionalFilesهای دریافتی است:
[Generator] public class NotifyPropertyChangedGenerator : ISourceGenerator { public void Initialize(GeneratorInitializationContext context) { } public void Execute(GeneratorExecutionContext context) { var customRootNamespace = context.GetMSBuildProperty("SourceGenerator_CustomRootNamespace", "Test"); var globalLoggingSwitch = context.GetMSBuildProperty("SourceGenerator_EnableLogging", "false"); var emitLoggingGlobal = globalLoggingSwitch.Equals("true", StringComparison.OrdinalIgnoreCase); foreach (var file in context.AdditionalFiles) { var perFileLoggingSwitch = context.GetAdditionalFilesOption(file, "SourceGenerator_EnableLogging"); var emitLogging = string.IsNullOrWhiteSpace(perFileLoggingSwitch) ? emitLoggingGlobal // allow the user to override the global logging on a per-file basis : perFileLoggingSwitch.Equals("true", StringComparison.OrdinalIgnoreCase); // add the source with or without logging... }
داتنت ۷ ریلیز شد!
.NET 7 brings your apps increased performance and new features for C# 11/F# 7, .NET MAUI, ASP.NET Core/Blazor, Web APIs, WinForms, WPF and more. With .NET 7, you can also easily containerize your .NET 7 projects, set up CI/CD workflows in GitHub actions, and achieve cloud-native observability.
Thanks to the open-source .NET community for your numerous contributions that helped shape this .NET 7 release. 28k contributions made by over 8900 contributors throughout the .NET 7 release!
.NET remains one of the fastest, most loved, and trusted platforms with an expansive .NET package ecosystem that includes over 330,000 packages.
In this section, I’m going to cover how you can use SignalR outside of a Hub. In most asp.net core applications, you will likely want to communicate with the connect clients from within your application but outside of a Hub. You can accomplish this by using the HubContext.
For example, an ASP.NET Core MVC Controller or any other class that is instantiated by ASP.NET Core’s Dependency Injection.
The HubContext allows you to send messages to your connected clients. It has many of the same features to communicate with clients as when you are inside of a Hub.