عنوان:

‫مدیریت برنامه‌های مبتنی بر فایل در NET 11.: فراتر از یک فایل واحد


نویسنده: وحید نصیری
تاریخ: ۱۴۰۵/۰۳/۲۱ ۰۷:۱۰
آدرس: www.dntips.ir
تغییرات جدید در نسخه پیش‌نمایش .NET 11، تحول بزرگی در نحوه توسعه برنامه‌های مبتنی بر فایل (File-based Applications) یا همان اسکریپت‌های تک‌فایلی ایجاد کرده است. مدیریت برنامه‌های کوچک، ابزارهای اتوماسیون و نمونه‌کدهای اولیه (Prototyping) که پیش از این به دلیل محدودیت در تفکیک کد، پس از مدتی شلوغ و غیرقابل‌نگهداری می‌شدند، اکنون با معرفی دایرکتیوهای جدید بسیار ساده‌تر و ساختاریافته‌تر شده است. در این مقاله، به بررسی دقیق این ویژگی‌های جدید، مکانیزم کارکرد دایرکتیوهای #:include و #:ref و قوانین حاکم بر آن‌ها در .NET 11 می‌پردازیم.

برنامه‌های مبتنی بر فایل (مانند Top-level Statements بدون فایل پروژه csproj) همواره گزینه‌ای عالی برای پیاده‌سازی سریع ایده‌ها بوده‌اند. با این حال، بزرگ شدن حجم کد معمولاً توسعه‌دهنده را مجبور می‌کرد که پروژه را به یک ساختار استاندارد MSBuild (همراه با فایل .csproj و فولدرهای متعدد) تبدیل کند.
در .NET 11، مایکروسافت با معرفی قابلیت تکه‌تکه کردن کد (Code Splitting) بدون نیاز به ایجاد پروژه، این مرز را جابه‌جا کرده است. اکنون این قابلیت‌ها به صورت بومی (Native) پشتیبانی می‌شوند و دیگر نیازی به فعال‌سازی Feature Flagها یا فلگ‌های تجربی ندارند.

دایرکتیو #:include: ادغام متنی فایل‌ها
دایرکتیو #:include به شما این امکان را می‌دهد که فایل‌های کمکی (Helpers)، مدل‌ها یا هر تکه کد دیگری را در فایل اصلی خود ادغام کنید، بدون اینکه جریان کاری ساده و بدون پروژه (Project-less) را از دست بدهید.
عملکرد این دایرکتیو شبیه به مکانیسم include# در زبان ++C یا هدرها است؛ یعنی محتوای فایل مقصد را کامپایلر به صورت متنی در همان نقطه از فایل مبدا در نظر می‌گیرد.
نمونه کد: فرض کنید می‌خواهیم متدهای کمکی و مدل‌های خود را از فایل اصلی جدا کنیم:
// main.cs
#:include helpers.cs
#:include models/customer.cs

Console.WriteLine(Helpers.FormatOutput(new Customer()));
نکته: برای راحتی توسعه‌دهندگان، کامپایلر Roslyn در نسخه جدید، قابلیت Editor Completion (تکمیل خودکار کد یا همان IntelliSense) را برای این دایرکتیو اضافه کرده است. بنابراین هنگام تایپ مسیر فایل‌ها در محیط IDE، ادیتور به شما در انتخاب فایل درست کمک می‌کند.

دایرکتیو#:ref: ارجاع به فایل‌ها به عنوان کتابخانه
تفاوت اساسی میان برنامه‌نویسی ساختاریافته و اسکریپت‌نویسی معمولی، نحوه مدیریت وابستگی‌ها است. در کنار ادغام متنی، .NET 11 دایرکتیو قدرتمند #:ref را معرفی کرده است.
این دایرکتیو به شما اجازه می‌دهد که یک فایل #C دیگر را دقیقاً مانند یک کتابخانه (Library) ارجاع دهید. در این حالت، فضای نام (Namespace) و ساختار فایل مقصد کاملاً حفظ می‌شود. نکته برجسته این است که این دایرکتیو از وابستگی‌های گذرا (Transitive References) نیز پشتیبانی می‌کند؛ یعنی اگر فایل الف به فایل ب ارجاع دهد و فایل ب به فایل ج، فایل اصلی به تکه‌های فایل ج نیز دسترسی خواهد داشت.
نمونه کد:
// lib.cs
namespace MyLib;

public static class Greeter
{
    public static string Greet(string name) => $"Hello, {name}!";
}

// app.cs
#:ref lib.cs

// دسترسی به متد با استفاده از فضای نام تعریف شده در فایل مرجع
Console.WriteLine(MyLib.Greeter.Greet("World"));

قوانین کامپایلر و نحوه رفتار با دایرکتیوهای تکراری
برای جلوگیری از رفتارهای غیرمنتظره در زمان کامپایل، SDK دات‌نت قوانین مشخصی را برای مدیریت دایرکتیوها (به ویژه زمانی که فایل‌ها به صورت گذرا یکدیگر را فراخوانی می‌کنند) وضع کرده است:
  • پشتیبانی از تکرار در دایرکتیوهای ساختاری: دایرکتیوهای #:project و #:ref می‌توانند به صورت تکراری در فایل‌های مختلف صدا زده شوند. این رفتار دقیقاً با رفتار آیتم‌ها در MSBuild مطابقت دارد و مشکلی در کامپایل ایجاد نمی‌کند.
  • تشخیص خطا در سایر دایرکتیوهای تکراری: بر خلاف موارد بالا، اگر دایرکتیوهای دیگر به صورت تکراری در میان فایل‌های گوناگونِ ادغام‌شده (Included Files) دیده شوند، کامپایلر به جای نادیده گرفتن بی‌صدا، یک خطای تشخیصی (Diagnostic Error) صادر می‌کند تا توسعه‌دهنده از تداخل‌های احتمالی باخبر شود.
  • حذف فاق‌های ویژگی (Feature Flags): پردازش دایرکتیوها به صورت گذرا (Transitively) در داخل فایل‌های Include شده، اکنون به پایداری کامل رسیده و بدون نیاز به هیچ تنظیمات اضافی کار می‌کند.

نتیجه‌گیری
تغییرات برنامه‌های مبتنی بر فایل در .NET 11، فاصله میان یک اسکریپت ساده و یک پروژه کامل را به حداقل رسانده است. با به کارگیری مکانیزم‌های #:include و #:ref، توسعه‌دهندگان اکوسیستم دات‌نت اکنون می‌توانند کدهای خود را به شکلی تمیز، ماژولار و قابل‌نگهداری مدیریت کنند، بدون اینکه درگیر پیچیدگی‌های ساختاری فایل‌های .csproj شوند. این ویژگی‌ها سرعت توسعه برنامه‌های سبک، ابزارهای خط فرمان (CLI Tools) و ابزارهای اتوماسیون را به شدت افزایش خواهد داد.