عنوان:

‫تغییر خوشایند در کلاس Program در .NET 10: دیگر نیازی به public partial نیست!


نویسنده: وحید نصیری
تاریخ: ۱۴۰۴/۰۸/۲۹ ۱۳:۲۹
آدرس: www.dntips.ir
اگر با پروژه‌های ASP.NET Core کار می‌کنید و از تست‌های یکپارچه‌سازی (Integration Tests) با WebApplicationFactory استفاده می‌کنید، حتماً این تغییر کوچک، اما مفید در .NET 10 شما را خوشحال خواهد کرد. در ادامه به‌طور کامل به بررسی این تغییر می‌پردازیم و می‌بینیم چرا دیگر لازم نیست آن خط کد اضافی را نگه داریم.

مقدمه
از زمان معرفی دستورات سطح بالا (Top-level statements) در .NET 6، فایل Program.cs در پروژه‌های ASP.NET Core بسیار ساده‌تر و تمیزتر شد. دیگر نیازی به نوشتن کلاس Program کامل و متد Main نبود؛ کامپایلر خودش یک کلاس Program تولیدشده (generated) می‌ساخت و کد شما را داخل آن قرار می‌داد. اما این سادگی یک مشکل کوچک برای تست‌نویسان ایجاد کرد: کلاس Program تولیدشده به صورت پیش‌فرض internal بود و WebApplicationFactory نیاز به یک نوع public داشت تا بتواند اپلیکیشن را بوت کند. در نتیجه، مجبور بودیم یک ترفند کوچک به کار ببریم.

توضیح مسئله
وقتی می‌خواهید تست‌های یکپارچه‌سازی بنویسید، معمولاً چیزی شبیه این دارید:
public class MyIntegrationTests : IClassFixture<WebApplicationFactory<Program>>
{
    private readonly WebApplicationFactory<Program> _factory;

    public MyIntegrationTests(WebApplicationFactory<Program> factory)
    {
        _factory = factory;
    }

    // تست‌های شما...
}
در نسخه‌های قبلی (.NET 6 تا .NET 9)، اگر از top-level statements استفاده می‌کردید، کلاس Program تولیدشده internal بود و پروژه تست (که معمولاً در assembly جداگانه است) نمی‌توانست به آن دسترسی پیدا کند. خطای کامپایل می‌گرفتید:
"Program is inaccessible due to its protection level".

راه‌حل قدیمی
برای حل این مشکل، جامعه توسعه‌دهندگان یک راه‌حل ساده و رایج پیدا کرد: اضافه کردن یک partial class عمومی در انتهای فایل Program.cs:
var builder = WebApplication.CreateBuilder(args);
// ... تنظیمات اپلیکیشن شما ...

var app = builder.Build();
// ... تنظیمات pipeline ...

app.Run();

// این خط جادویی!
public partial class Program { }
با این کار، چون کلاس partial بود، با کلاس تولیدشده کامپایلر ادغام می‌شد و visibility آن به public تغییر می‌کرد. مشکل حل می‌شد و همه خوشحال بودند!
(البته گزینه‌های دیگری مثل استفاده از InternalsVisibleTo هم وجود داشت، اما این روش تمیزتر و پراستفاده‌تر بود.)

راه‌حل جدید در .NET 10
خوشبختانه تیم .NET به این درد مشترک توجه کرده و در .NET 10 (که اکنون منتشر شده)، کلاس Program تولیدشده در پروژه‌های ASP.NET Core به صورت پیش‌فرض public است. یعنی دیگر نیازی به اضافه کردن آن خط public partial class Program { } نیست!
حالا می‌توانید مستقیماً از WebApplicationFactory استفاده کنید، بدون هیچ تنظیم اضافی. کد Program.cs شما دوباره کاملاً تمیز و مینیمال می‌ماند.
علاوه بر این، مایکروسافت یک آنالایزر جدید به نام ASP0027 اضافه کرده که اگر هنوز آن خط قدیمی را داشته باشید، به شما هشدار می‌دهد:
ASP0027: Unnecessary public Program class declaration
استفاده از public partial class Program { } برای عمومی کردن کلاس Program تولیدشده دیگر لازم نیست.
حتی یک Code Fix هم وجود دارد که با یک کلیک آن خط اضافی را حذف می‌کند. خیلی حرفه‌ای و کاربرپسند!

نکته مهم: این تغییر فقط برای پروژه‌های ASP.NET Core اعمال می‌شود، چون مشکل اصلی در استفاده از WebApplicationFactory بود. در پروژه‌های کنسولی معمولی، کلاس Program تولیدشده همچنان internal می‌ماند (مگر اینکه خودتان partial public اضافه کنید).

نتیجه‌گیری
این تغییر کوچک در .NET 10 یکی از آن بهبودهای کیفیتی است که نشان می‌دهد تیم توسعه .NET واقعاً به بازخورد جامعه توجه می‌کند. دیگر نیازی به هک‌های کوچک برای تست نیست و کد شما تمیزتر می‌ماند. اگر پروژه‌های قدیمی دارید، بعد از ارتقا به .NET 10 حتماً به هشدارهای ASP0027 توجه کنید و آن خطوط اضافی را حذف کنید – هم کد تمیزتر می‌شود و هم از امکانات جدید آنالایزرها بهره می‌برید.


مشاهده مطلب اصلی