لینوکس برای توسعهدهندگان داتنت: از ویندوز تا کراس-پلتفرم؛ بخش دوم: کدنویسی کراس-پلتفرم در داتنت
نویسنده: وحید نصیری
تاریخ: ۱۴۰۴/۰۴/۲۶ ۰۸:۱۰
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
string concatenation) یک ضد-الگو (anti-pattern) است. کلاس System.IO.Path مجموعهای غنی از ابزارها را برای کار درست با مسیرها فراهم میکند.Path.Combine (یادآوری): همیشه برای ترکیب کردن بخشهای مختلف یک مسیر از این متد استفاده کنید.Path.GetFullPath(string path): یک مسیر نسبی (relative) را به مسیر کامل و مطلق (absolute) تبدیل میکند. این متد بسیار مفید است زیرا نحوهی مدیریت مسیرهای نسبی در پلتفرمهای مختلف، متفاوت است.Path.GetDirectoryName(string path): نام پوشهی حاوی یک فایل یا پوشه را برمیگرداند.Path.GetFileName(string path): نام فایل (با پسوند) را از یک مسیر کامل استخراج میکند.Environment.GetFolderPath() استفاده کنید. این متد یک مقدار از شمارندهی Environment.SpecialFolder را به عنوان ورودی میگیرد و مسیر صحیح را در هر سیستمعاملی برمیگرداند.// این کد مسیر صحیح را در هر سه پلتفرم اصلی پیدا میکند
var appDataFolder = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
var myAppFolder = Path.Combine(appDataFolder, "MyCoolApp");
var logFilePath = Path.Combine(myAppFolder, "events.log");
// قبل از نوشتن، اطمینان حاصل میکنیم که پوشه وجود دارد
Directory.CreateDirectory(myAppFolder);
File.AppendAllText(logFilePath, $"Log entry at {DateTime.Now}{Environment.NewLine}");
Console.WriteLine($"Log file created at: {logFilePath}");C:\Users\YourUser\AppData\Roaming\MyCoolApp\events.log/home/youruser/.config/MyCoolApp/events.log/Users/youruser/.config/MyCoolApp/events.logset MYAPP_CONNECTION_STRING="some_value"$env:MYAPP_CONNECTION_STRING="some_value"export MYAPP_CONNECTION_STRING="some_value"Environment.GetEnvironmentVariable استفاده میکنیم.string connStr = Environment.GetEnvironmentVariable("MYAPP_CONNECTION_STRING");
if (string.IsNullOrEmpty(connStr))
{
Console.WriteLine("Connection string is not set!");
}
else
{
Console.WriteLine("Using connection string from environment.");
// Connect to database using connStr...
}IConfiguration به طور پیشفرض متغیرهای محیطی را میخواند و آنها را بر مقادیر موجود در appsettings.jsonاولویت میدهد. این ویژگی برای محیطهای داکر و پروداکشن فوقالعاده کاربردی است."Logging": { "LogLevel": { "Default": "Information" } }export Logging__LogLevel__Default="Warning"
git یا ffmpeg). برای این کار از کلاس System.Diagnostics.Process استفاده میشود.cmd.exe، powershell.exe یا یک فایل .bat را اجرا کنید.bash، zsh یا یک اسکریپت .sh را اجرا میکنید.using System.Diagnostics;
var processStartInfo = new ProcessStartInfo
{
FileName = "ls", // در ویندوز میتوانید "dir" را جایگزین کنید
Arguments = "-l /home/youruser", // در ویندوز مثلاً "C:\\Users"
RedirectStandardOutput = true, // برای خواندن خروجی
UseShellExecute = false, // مهم: برای ریدایرکت کردن خروجی باید false باشد
CreateNoWindow = true, // پنجره جدیدی باز نشود
};
using var process = new Process { StartInfo = processStartInfo };
process.Start();
string output = process.StandardOutput.ReadToEnd(); // خواندن تمام خروجی
process.WaitForExit();
Console.WriteLine(output);.sh) را اجرا کنید، ابتدا باید به آن مجوز اجرا بدهید: chmod +x your_script.sh.Arguments قرار ندهید تا از حملات Command Injection جلوگیری کنید.UseShellExecute: تنظیم این گزینه روی false به شما کنترل بیشتری بر روی پروسه (مانند خواندن خروجی) میدهد و روش امنتری محسوب میشود.System.Runtime.InteropServices.RuntimeInformationusing System.Runtime.InteropServices;
public void PerformPlatformSpecificAction()
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
Console.WriteLine("Running on Windows. Accessing registry...");
// کد مخصوص ویندوز در اینجا قرار میگیرد
// مثلاً: Microsoft.Win32.Registry.CurrentUser.OpenSubKey(...)
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
Console.WriteLine("Running on Linux. Reading from /etc/os-release...");
// کد مخصوص لینوکس در اینجا قرار میگیرد
// مثلاً: File.ReadAllText("/etc/os-release")
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
Console.WriteLine("Running on macOS.");
// کد مخصوص مک در اینجا قرار میگیرد
}
}if/else در سراسر کد، بهتر است منطق وابسته به پلتفرم را پشت یک اینترفیس (Interface) مخفی کنید و با استفاده از تزریق وابستگی (Dependency Injection)، پیادهسازی صحیح را در زمان اجرا به برنامه تزریق کنید.public interface INotificationService { void ShowNotification(string message); }public class WindowsNotificationService : INotificationService { ... } (مثلاً با استفاده از Toast Notifications)public class LinuxNotificationService : INotificationService { ... } (مثلاً با استفاده از notify-send در خط فرمان)if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
services.AddSingleton<INotificationService, WindowsNotificationService>();
}
else
{
services.AddSingleton<INotificationService, LinuxNotificationService>(); // fallback
}