پاسخ به بازخوردهای پروژهها
چند متد الحاقی پیشنهادی
متد پیش فرض دات نت برای بررسی مقادیر String مناسب است. شاید با ترکیب دو متد IsNullOrWhiteSpace و IsNullOrEmpty بتوان متد بهتری ساخت. متد پیشنهادی من به صورت زیر است:
/// <summary> /// It returns true if string is null or empty or just a white space otherwise it returns false. /// </summary> /// <param name="input">Input String</param> /// <returns>bool</returns> public static bool IsEmpty(this string input) { return string.IsNullOrEmpty(input) || string.IsNullOrWhiteSpace(input); }
بازخوردهای پروژهها
خطا در اجرای برنامه
با عرض سلام و خسته نباشید من با اجرای برنامه با خطای زیر مواجه میشم (ویندوز 7 و دات نت فریمورک 4 رو هم نصب کردم) :
و همینطور در زمانی که برنامه را در ویژوال استودیو اجرا میکنم خطای زیر را میدهد:
Unknown build error, 'Could not load file or assembly 'file:///C:\Users\VAHID\Downloads\DNTProfiler-1.8.1129.0\DNTProfiler-1.8.1129.0\DNTProfiler\obj\Release\DNTProfiler.exe' or one of its dependencies. The module was expected to contain an assembly manifest.'
پروژهها
DNTProfiler
DNTProfiler پروژهی پروفایلر سورس بازی است که با EF 6.x و همچنین NHibernate 4.x سازگار است.
برای استفادهی از آن نیاز به نصب دات نت فریم ورک 4 بر روی سیستم شما است. همچنین نیاز است کتابخانهی کلاینت آنرا به پروژهی خود نیز اضافه کنید. اطلاعات بیشتر
- محل دریافت آخرین نگارش آن: https://github.com/VahidN/DNTProfiler/releases
- بستهی نیوگت EF پروژه: DNTProfiler.EntityFramework.Core
- بستهی نیوگت NH پروژه: DNTProfiler.NHibernate.Core
برای استفادهی از آن نیاز به نصب دات نت فریم ورک 4 بر روی سیستم شما است. همچنین نیاز است کتابخانهی کلاینت آنرا به پروژهی خود نیز اضافه کنید. اطلاعات بیشتر
- محل دریافت آخرین نگارش آن: https://github.com/VahidN/DNTProfiler/releases
- بستهی نیوگت EF پروژه: DNTProfiler.EntityFramework.Core
- بستهی نیوگت NH پروژه: DNTProfiler.NHibernate.Core
نظرات نظرسنجیها
اگر بخواهید کنار دات نت بر روی یک پلتفرم یا زبان دیگری نیز کار کنید کدام را انتخاب می کنید؟
بله در موردش کمی مطالعه داشتم، 2-3 سالی هست توی خیلی از اپهای آموزش برنامه نویسی اندروید هم یادگیریشو گذاشتن، حتی برخی به عنوان اولین زبان اندروید نویسی یادش میدن. چون خودم دات نت رو یک محیط یکپارچه میبینم و تفاوت خاصی بین c# یا vb.net نمیبینم، پلتفرم جاوا رو هم یک محیط واحد میبینم! به هرحال همه زبانهای محیط جاوا در نهایت به کد ماشین مجازی جاوا ترجمه میشن، و قدرت یکسانی دارن. اگر میفرمایید یک گزینه دیگر به عنوان کاتلین هم اضافه میکنم، یا عنوان جاوا رو به "یکی از زبانهای پلتفرم جاوا، مثل جاوا، کاتلین، اسکالا و ..." تغییر میدم.
فکر میکنم اگر گزینهی استفاده از «وب سرویسها» را هم اضافه کنید بهتر باشد (این روش در دنیای دات نت حداقل مرسومتر است). برای مثال اگر نیاز به اطلاعات برنامهی دیگری باشد، با ایجاد یک وب سرویس (asmx، wcf یا web api و امثال آن)، سطح مناسبی را در اختیار مصرف کننده قرار میدهیم. همچنین این وب سرویسها حالت اجرایی هم میتوانند داشته باشند؛ مثلا فراخوانی یک متد در یک برنامهی دیگر.
علاوه بر روش وب سرویسها که خیلی مرسوم هست، روش دیگر اینکار در شبکههای داخلی سازمانی، استفاده از Linked serverهای SQL Server هستند (برای به اشتراک گذاری اطلاعات در بین برنامهها). پیاده سازی Linked serverهای SQL Server هم یکی دیگر از روشهای نوشتن برنامههای توزیع شدهی داخل سازمانی هستند.
معمولا وقتی صحبت از هک میشود بیشتر وب سایتها مدنظر هستند و کمتر به نرم افزارهای محیط desktop توجه میشود اما در محیط desktop هم امنیت بسیار مهم است.
یکی از مواردی که در رابطه با windows formها (دات نتی و غیر دات نتی) بسیار به آن برخورد کرده ام اعمال دسترسی کاربر به قسمتهای مختلف فرم با مخفی یا غیر فعال کردن دکمهها و کنترلهای فرم است. به این صورت که در هنگام لود فرم اصلی با توجه به دسترسی کاربر بعضی منوها مخفی میشوند و در لود هر فرم هم بعضی از دکمهها و کنترلهای روی فرم مخفی یا غیر فعال میشوند. همین!
یکی از مواردی که در رابطه با windows formها (دات نتی و غیر دات نتی) بسیار به آن برخورد کرده ام اعمال دسترسی کاربر به قسمتهای مختلف فرم با مخفی یا غیر فعال کردن دکمهها و کنترلهای فرم است. به این صورت که در هنگام لود فرم اصلی با توجه به دسترسی کاربر بعضی منوها مخفی میشوند و در لود هر فرم هم بعضی از دکمهها و کنترلهای روی فرم مخفی یا غیر فعال میشوند. همین!
اما اگر کاربر به کمک ابزاری بتواند منوها و کنترلهای مخفی فرم را نمایش دهد و منوها و کنترلهای غیرفعال را فعال کند چی؟
کلاس زیر را در نظر بگیرید :
public class HackWindowsForms { struct POINTAPI { public int X; public int Y; } [DllImport("user32.dll")] static extern int EnumChildWindows(int hWndParent, EnumChildCallbackDelegate enumChildCallback, int lParam); [DllImport("user32.dll")] static extern int EnableWindow(int hwnd, int fEnable); [DllImport("user32.dll")] static extern int WindowFromPoint(int x, int y); [DllImport("user32.dll")] static unsafe extern int GetCursorPos(POINTAPI* lpPoint); delegate int EnumChildCallbackDelegate(int hwnd, int lParam); public static void EnableThisWindowControls() { unsafe { POINTAPI cursorPosition = new POINTAPI(); GetCursorPos(&cursorPosition); int winWnd = WindowFromPoint(cursorPosition.X, cursorPosition.Y); EnumChildWindows(winWnd, EnumChildCallback, 0); } } static int EnumChildCallback(int hwnd, int lParam) { EnableWindow(hwnd, 1); EnumChildWindows(hwnd, EnumChildCallback, 0); return 1; } }
private void button1_MouseUp(object sender, MouseEventArgs e) { HackWindowsForms.EnableThisWindowControls(); MessageBox.Show("حالا روی دکمه مورد نظر کلیک کنید و کلید space را فشار دهید.", "", MessageBoxButtons.OK, MessageBoxIcon.Asterisk, MessageBoxDefaultButton.Button1, MessageBoxOptions.RtlReading); }
نمونه کد مشابهی هم برای نمایش منوها و کنترلهای مخفی شده میتوان نوشت.
اما راه حل چیست؟
قبل از اجرای هر عملی که احتیاج به دسترسی دارد، دسترسی کاربر چک شود و فقط به غیر فعال و مخفی کردن کنترلها بسنده نشود. مثلا اگر دکمه ویرایش را غیر فعال کرده ایم در کلیک آن هم دسترسی چک شود.
نظرات مطالب
آشنایی با Refactoring - قسمت 6
علاوه بر مطالبی که اونطرف نوشتم، فورم اصلی RIA Services اینجا است: [^]. بگردید از این مورد زیاد دارد.
روشهای زیادی برای ایجاد یک وهلهی Singleton وجود دارند. وهلهای که در طول عمر یک برنامه، تنها یکبار ایجاد شده و حفظ میشود. برای مثال شاید متداولترین حالت آن که در بسیاری از کدها دیده میشود، تعریف یک متغیر استاتیک در کلاس، غیرعمومی تعریف کردن سازندهی کلاس و وهله سازی این فیلد استاتیک در صورت نال بودن آن است:
هرچند این روش کار میکند اما thread-safe نیست. به این معنا که ممکن است دو ترد در آن واحد به بررسی قسمت ?? instance_ بپردازند و چون هنوز نال است، دوبار وهله سازی کلاس، با فراخوانی new WrongSingleton صورت خواهد گرفت و هر ترد در آن لحظه به وهلهی متفاوتی دسترسی خواهد داشت.
راه حلهای زیادی برای رفع این مشکل با اعمال مباحث قفل گذاری تا نکات ریز مربوط به کامپایلر وجود دارند که لیست آنها را در اینجا میتوانید مطالعه کنید.
از دات نت 4 به بعد با معرفی الگوی Lazy، امکان پیاده سازی lazy thread safe singletons به صورت توکار در دسترس میباشد. نمونهای از آن در کدهای IoC Container معروفی به نام StructureMap بکار رفتهاست:
در اینجا کلاس ObjectFactory یک وهله از کلاس Container را در اختیار مصرف کننده قرار میدهد؛ با این شرایط:
- چون این وهله توسط کلاس Lazy محصور شدهاست، صرفا در اولین بار دسترسی به آن، نمونه سازی خواهد شد. این مورد سبب کاهش مصرف حافظهی برنامه و همچنین بالا رفتن سرعت برپایی اولیهی آن میشود. بسیاری از اشیایی که در یک برنامه تعریف میشوند، شاید الزاما جهت ارائه راه حلی برای مسالهای خاص، مورد استفاده قرار نگیرند. تعریف آنها به صورت Lazy، سربار نمونه سازی الزامی آنها را حذف خواهد کرد و آنرا به اولین بار استفاده از شیء مورد نظر، به تعویق خواهد انداخت.
- با استفاده از LazyThreadSafetyMode.ExecutionAndPublication، چندین ترد میتوانند به خاصیت Container دسترسی پیدا کنند، اما تنها یکی از آنها موفق به وهله سازی این کلاس خواهد شد. البته حالت ExecutionAndPublication، حالت پیش فرض است و الزاما نیازی به ذکر آن نیست.
اینبار بازنویسی کلاس ابتدای بحث با توجه به نکات ذکر شده به صورت زیر خواهد بود:
- در آن سازندهی کلاس، خصوصی تعریف شدهاست.
- تنها وهلهی در دسترس کلاس، به صورت استاتیک و نمونه سازی کلاس، توسط کلاس Lazy با پارامتر LazyThreadSafetyMode.ExecutionAndPublication انجام میشود.
- علت استفاده از lambda در سازندهی کلاس Lazy، امکان دسترسی به اعضای private کلاس، از طریق یک خاصیت static است.
public class WrongSingleton { static WrongSingleton _instance; WrongSingleton() { } public static WrongSingleton Instance { get { return _instance ?? (_instance = new WrongSingleton()); } } }
راه حلهای زیادی برای رفع این مشکل با اعمال مباحث قفل گذاری تا نکات ریز مربوط به کامپایلر وجود دارند که لیست آنها را در اینجا میتوانید مطالعه کنید.
از دات نت 4 به بعد با معرفی الگوی Lazy، امکان پیاده سازی lazy thread safe singletons به صورت توکار در دسترس میباشد. نمونهای از آن در کدهای IoC Container معروفی به نام StructureMap بکار رفتهاست:
public class Container { // ... } public static class ObjectFactory { private static readonly Lazy<Container> _containerBuilder = new Lazy<Container>(defaultContainer, LazyThreadSafetyMode.ExecutionAndPublication); public static Container Container { get { return _containerBuilder.Value; } } private static Container defaultContainer() { return new Container(); } }
- چون این وهله توسط کلاس Lazy محصور شدهاست، صرفا در اولین بار دسترسی به آن، نمونه سازی خواهد شد. این مورد سبب کاهش مصرف حافظهی برنامه و همچنین بالا رفتن سرعت برپایی اولیهی آن میشود. بسیاری از اشیایی که در یک برنامه تعریف میشوند، شاید الزاما جهت ارائه راه حلی برای مسالهای خاص، مورد استفاده قرار نگیرند. تعریف آنها به صورت Lazy، سربار نمونه سازی الزامی آنها را حذف خواهد کرد و آنرا به اولین بار استفاده از شیء مورد نظر، به تعویق خواهد انداخت.
- با استفاده از LazyThreadSafetyMode.ExecutionAndPublication، چندین ترد میتوانند به خاصیت Container دسترسی پیدا کنند، اما تنها یکی از آنها موفق به وهله سازی این کلاس خواهد شد. البته حالت ExecutionAndPublication، حالت پیش فرض است و الزاما نیازی به ذکر آن نیست.
اینبار بازنویسی کلاس ابتدای بحث با توجه به نکات ذکر شده به صورت زیر خواهد بود:
public sealed class LazySingleton { private static readonly Lazy<LazySingleton> _instance = new Lazy<LazySingleton>(() => new LazySingleton(), LazyThreadSafetyMode.ExecutionAndPublication); private LazySingleton() { } public static LazySingleton Instance { get { return _instance.Value; } } }
- تنها وهلهی در دسترس کلاس، به صورت استاتیک و نمونه سازی کلاس، توسط کلاس Lazy با پارامتر LazyThreadSafetyMode.ExecutionAndPublication انجام میشود.
- علت استفاده از lambda در سازندهی کلاس Lazy، امکان دسترسی به اعضای private کلاس، از طریق یک خاصیت static است.
اشتراکها
بیانیه Software Craftsmanship
بیانیه صنعتگران نرم افزار، در جهت تولید سیستمهای کارآمد تر، سازگارتر و قویتر(صرف نظر از خواستههای کاربران ) توسط بزرگان این حوزه صادر شده است و توسعه دهندگان نرم افزار از سراسر جهان با مطالعه و اجرای بندهای چهار گانه آن(در صورت اشتراک نظر) کمک به پیشرفت این جامعه بزرگ مینماید.
این بیانیه رو توسط افراد زیادی مطالعه و امضا شده است.
این بیانیه رو توسط افراد زیادی مطالعه و امضا شده است.