TGViewer
C# Geeks (.NET) C# Geeks (.NET) @csharpgeeks · 550 subscribers
Post #597 224
Implementation with .NET Keyed Services
پیاده‌سازی با استفاده از Keyed Services در NET. 🧩
در NET 8.، مایکروسافت قابلیتی به نام Keyed Services معرفی کرد که برای این سناریو کاملاً ایده‌آل است. این قابلیت به ما اجازه می‌دهد چند پیاده‌سازی از یک interface یکسان را ثبت کنیم و بر اساس نام (کلید) آن‌ها را دریافت کنیم. 🔑

1️⃣ Registering the Services

ما هر دو hasher را در فایل Program.cs ثبت می‌کنیم و به هرکدام یک کلید منحصربه‌فرد می‌دهیم:
// Register the implementations with specific keys
builder.Services.AddKeyedSingleton<IPasswordHasher, Pbdkf2PasswordHasher>("legacy");
builder.Services.AddKeyedSingleton<IPasswordHasher, Argon2PasswordHasher>("modern");

// (Optional) Register the modern one as the default for other services
builder.Services.AddSingleton<IPasswordHasher, Argon2PasswordHasher>();


2️⃣ The Login Command Handler

حالا منطق مهاجرت را پیاده‌سازی می‌کنیم. هر دو hasher را با استفاده از اتریبیوت [FromKeyedServices] تزریق می‌کنیم. 🧪
public class LoginCommandHandler(
IUserRepository userRepository,
[FromKeyedServices("modern")] IPasswordHasher newHasher,
[FromKeyedServices("legacy")] IPasswordHasher legacyHasher)
{
public async Task<AuthenticationResult> Handle(LoginCommand command)
{
var user = await userRepository.GetByEmailAsync(command.Email);
if (user is null)
{
return AuthenticationResult.Fail();
}

// 1. Try the new algorithm first (Happy Path)
if (newHasher.Verify(user.PasswordHash, command.Password))
{
return AuthenticationResult.Success(user);
}

// 2. Fallback: Check if it's a legacy hash
if (legacyHasher.Verify(user.PasswordHash, command.Password))
{
// 3. MIGRATION STEP: Re-hash and save
var newHash = newHasher.Hash(command.Password);

user.UpdatePasswordHash(newHash);
await userRepository.SaveChangesAsync();

return AuthenticationResult.Success(user);
}

return AuthenticationResult.Fail();
}
}

این کد تضمین می‌کند که کاربران فعال به صورت خودکار ارتقا پیدا کنند.
بعد از چند ماه، بخش عمده‌ای از کاربران شما روی الگوریتم جدید خواهند بود. 📈

Real-World Improvements
بهبودهای دنیای واقعی 🌍

در حالی که پیاده‌سازی بالا کار می‌کند، دو بهبود وجود دارد که آن را production-ready می‌کند.

1️⃣ Algorithm Prefixes
پیشوند الگوریتم‌ها

اتکا به روش «trial and error» برای verify کردن کار می‌کند، اما تمیزتر این است که دقیقاً بدانیم هر هش با چه الگوریتمی ساخته شده است.
الگوریتم‌های استاندارد معمولاً یک prefix دارند
(مثلاً Bcrypt با $2a$ یا $2b$ شروع می‌شود).
می‌توان از این موضوع برای مسیریابی بهینه استفاده کرد:
public bool IsLegacyHash(string hash)
{
// This assumes we're storing a prefix for PBKDF2 hashes. Something to consider.
return hash.StartsWith("pbkdf2$");
}

مزیت دیگر این کار این است که می‌توانیم مستقیماً از دیتابیس کوئری بگیریم و کاربرانی که هنوز روی فرمت قدیمی هستند را پیدا کنیم. 🔍

2️⃣ Feature Flags
فلگ‌های ویژگی 🚩

انجام یک write در دیتابیس هنگام لاگین باعث افزایش latency می‌شود. اگر ترافیک بالایی دارید، بهتر است کنترل این rollout را در دست بگیرید.
با قرار دادن منطق مهاجرت پشت یک Feature Flag، می‌توانید در صورت بالا رفتن فشار روی دیتابیس، مرحله‌ی نوشتن را غیرفعال کنید، در حالی که کاربران همچنان از مسیر fallback می‌توانند لاگین کنند.
if (await featureManager.IsEnabledAsync(FeatureFlags.MigratePasswords) &&
legacyHasher.Verify(user.PasswordHash, command.Password))
{
// Perform migration...
}


Finishing the Migration
پایان دادن به مهاجرت 🏁

بعد از مدتی (معمولاً چند ماه)، اکثر اکانت‌های فعال ارتقا پیدا می‌کنند.
سپس می‌توانید یک اسکریپت cleanup اجرا کنید تا هش‌های قدیمی باقی‌مانده را شناسایی کنید و کاربران مربوطه را مجبور کنید در لاگین بعدی پسورد خود را ریست کنند.
در این نقطه می‌توانید موارد زیر را حذف کنید:
• ثبت legacy hasher
• مسیر verification مربوط به legacy
• ءfeature flag
و مهاجرت کامل می‌شود. ✅
More from @csharpgeeks
  1. Sep 22, 2026یه مدتی قراره از دنیای NET. فاصله بگیرم، چون وقتشه برم سربازی. راستش نمیدونم این مدت رو چج…
  2. Sep 20, 2026🔥 حالا مشکل اصلی: Alert Storm فرض کن Database از دسترس خارج شده. ۱۰۰ Pod داری. هر Pod می‌…
  3. Sep 20, 2026🚨 طراحی سیستم Monitoring و Alerting در یک سیستم بزرگ فرض کن ساعت ۳ صبح است. سیستم شما با…
  4. Sep 19, 2026#Engineering_Leadership تصمیم نگرفتن هم یک تصمیم است یه چیز عجیب توی تیم‌های مهندسی: گاهی…
  5. Sep 19, 2026☑ چک‌لیست آماده‌سازی تیم، فرایندها و زیرساخت برای توسعه با AI توجه: هیچ چک‌لیستی جهان‌شمول…
  6. Sep 19, 2026📌پایان یک انتظار طولانی: اعتبارسنجی ناهمگام (Async Validation) در NET 11.
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →