مطالب
لینک‌های هفته دوم آذر

وبلاگ‌ها و سایت‌های ایرانی


Visual Studio


امنیت

ASP. Net


طراحی وب


اس‌کیوال سرور


سی‌شارپ


عمومی دات نت


متفرقه


اشتراک‌ها
شروع کار با OpenAI و ChatGPT با #C

در شروع کار با تکنولوژی‌های جدید ممکنه همیشه اولش کمی پیچیده بنظر بیاد و زمان بر باشه. توی این مخزن(Repository) گیت‌هاب سعی کردم چند مثال از کار با OpenAI API با دات نت و به زبان سی شارپ بزارم. 

از ساده‌ترین حالت فراخوانی API تا مدل‌های یکم پیچیده مثل یک ربات تلگرامی برای چت با ChatGPT و همچنین تولید عکس‌های خلاقانه بر اساس prompt‌های ورودی کاربر با استفاده از DALL-E.

به مرور سعی میکنم مثال‌های بیشتر و پیشرفته‌تری رو هم اضافه کنم تا برای اونایی که در شروع این راه هستند با حداقل اصطکاک یادگیری و در کمترین زمان بتوانند ایده‌های خود را بر اساس ChatGPT پیاده سازی کنند.

در تولید کدها و همچنین مستندسازی هم تا حد امکان سعی کردم از خود ChatGPT استفاده کنم!

شروع کار با OpenAI و ChatGPT با #C
نظرات مطالب
ثبت استثناهای مدیریت شده توسط ELMAH
در مطلب «نکات کار با استثناءها در دات نت» به این موارد بهتر پرداخته شده‌است:
«... در واقع استثنا‌ها حالت‌هایی هستند که غیرقابل پیش‌بینی هستند. این حالت‌ها می‌توانند یک خطای منطقی از طرف برنامه‌نویس و یا چیزی خارج کنترل برنامه‌نویس باشند (مانند خطاهای سیستم‌عامل، شبکه، دیسک). یعنی در بیشتر مواقع این نوع خطاها را نمی‌توان مدیریت کرد ...»
و یا
« ... در واقع استثناء‌ها بستگی به حالت‌های مختلفی دارد. در مثال اول وجود فایل حیاتی است ولی در حالت دوم بدون وجود فایل نیز برنامه می‌تواند به کار خود ادامه داده و فایل مورد نظر را از نو ایجاد کند ...»

بنابراین «حیاتی بودن» یک شرط در حال بررسی، معیاری هست برای صدور استثناء یا مدیریت آن. اگر حیاتی است، باید در همان نقطه کار خاتمه پیدا کند، استثناء مدیریت نشود و یا استثنایی مشخص صادر شود ( fail fast ).
نظرات مطالب
سایت‌های مهمی که از ASP.NET MVC استفاده می‌کنند
- خوب، اصلاحش کنید و به ASP.NET نگارش فعلی ویکی‌پدیا، MVC را هم اضافه کنید. ویکی پدیا به همین نحو مدیریت می‌شود.
- ماخذ این گفته، اسکات گاتری هست (دقیقه 52 این ویدیو). اسکات گاتری مدیر اجرایی Microsoft Azure و همچنین خیلی از تیم‌ها منجمله دات نت است. ایشان اخیرا به عنوان جانشین مدیر جدید مایکروسافت در قسمت‌های Cloud و Enterprise منصوب شده.
- این ماخذ اصلی را هم به ویکی‌پدیا اضافه کنید.

برای تکرار؛ روش تشخیص دستی
افزونه‌ی server spy مشخص می‌کند که برای ارائه سایت بینگ از IIS در حال استفاده است (یعنی ویندوز و ASP.NET در حالت کلی). افزونه‌ی ViewState Size مشخص می‌کند که در آن ViewState ایی وجود ندارد (یعنی وب فرم نیست).
نظرات مطالب
ASP.NET MVC #13
امکانات Data Annotation‌ها کار تیم EF یا به عبارتی طراحان اصلی دات نت است. بنابراین کمی زیاده روی است که عنوان کنیم غیراصولی هستند. شما در NHibernate چندین و چند روش تعریف نگاشت‌ها و روابط را دارید. از فایل‌های XML تا Data Annotation‌ها تا Fluent NH تا Mapping by code اخیر آن و غیره. تمام این‌ها هست برای برآوردن سلایق مختلف.
در EF Code first هم به همین ترتیب. شما حق انتخاب دارید. به شخصه از ترکیب هر دو حالت Data Annotation‌ها و Fluent API استفاده می‌کنم.
ViewModel فقط بحث مدیریت صحیح ارتباط با کلاینت است (نمایش اطلاعات View) و برعکس (دریافت اطلاعات از کاربر). بنابراین اگر از ViewModel استفاده می‌کنید، نیاز است از Data Annotation‌ها استفاده کنید تا اعتبار سنجی سمت کاربر (که به صورت خودکار توسط MVC اعمال و مدیریت می‌شود) کار کند.
نظرات مطالب
آشنایی با Refactoring - قسمت 7
بحث Refactoring در مورد طراحی کارهای شما معنا پیدا می‌کند؛ وگرنه اگر کتابخانه‌ی بسته دیگری، نیازهای خاص خودش را دیکته می‌کند، بدیهی است دست شما آنچنان باز نخواهد بود.
در مورد مطلبی که گفتید، بله می‌شود. در این حالت باید DataObject TypeName مربوط به ObjectDataSource را مشخص کنید: [^]
اگر می‌خواهید واقعا این اصول شیءگرایی را رعایت کنید، بهتر است به ASP.NET MVC کوچ کنید. Model binder آن، خودش به صورت خودکار این موارد را پوشش می‌دهد. نگارش بعدی ASP.NET Webforms هم کمی تا قسمتی از این Model binder رو به ارث برده ولی نه آنچنان که یک strongly typed view رو بتونید باهاش 100 درصد مثل MVC تعریف کنید.
در کل معماری ASP.NET Webforms مربوط به روزهای اول دات نت است و به نظر هم قرار نیست آنچنان تغییری بکند. به همین جهت MVC رو این وسط معرفی کرده‌اند.
نظرات مطالب
بارگذاری یک یوزرکنترل با استفاده از جی‌کوئری
بله. اگر پارامتر ورودی نداشت یک '{}' قرار دهید کفایت می‌کنه.
برای دات نت 2 کمی کار شما بیشتر می‌شود چون در VS2008 خیلی از موارد را خودکار اضافه می‌کند.
در این حالت یا باید ASP.NET AJAX Extensions روی سرور نصب باشد یا dll های آن‌را به صورت دستی به دایرکتوری bin برنامه اضافه کنید و یک ارجاع از آن‌ها را نیز به برنامه اضافه کنید.
همچنین وب کانفیگ را نیز باید ویرایش کنید تا این تغییر در آن لحاظ شود. (در غیر اینصورت کار نمی‌کند)
یک نکته دیگر هم اینکه بجای msg.d شما فقط msg را در asp.net 2‌ دارید و این d از 3.5 به بعد اضافه شده (در قسمت success و هنگام دریافت پاسخ از سرور توسط jQuery).
نظرات نظرسنجی‌ها
از چه روشی برای مدیریت ارتباطات و هماهنگی بین Application هایتان استفاده می کنید؟
فکر می‌کنم اگر گزینه‌ی استفاده از «وب سرویس‌ها» را هم اضافه کنید بهتر باشد (این روش در دنیای دات نت حداقل مرسوم‌تر است). برای مثال اگر نیاز به اطلاعات برنامه‌ی دیگری باشد، با ایجاد یک وب سرویس (asmx، wcf یا web api و امثال آن)، سطح مناسبی را در اختیار مصرف کننده قرار می‌دهیم. همچنین این وب سرویس‌ها حالت اجرایی هم می‌توانند داشته باشند؛ مثلا فراخوانی یک متد در یک برنامه‌ی دیگر.
علاوه بر روش وب سرویس‌ها که خیلی مرسوم هست، روش دیگر اینکار در شبکه‌های داخلی سازمانی، استفاده از Linked serverهای SQL Server هستند (برای به اشتراک گذاری اطلاعات در بین برنامه‌ها). پیاده سازی Linked serverهای SQL Server هم یکی دیگر از روش‌های نوشتن برنامه‌های توزیع شده‌ی داخل سازمانی هستند.
مطالب
بررسی Source Generators در #C - قسمت اول - معرفی
Source Generators که به همراه C# 9.0 ارائه شدند، یک فناوری نوین meta-programming است و به عنوان جزئی از پروسه‌ی استاندارد کامپایل برنامه، ظاهر می‌شود. هدف اصلی از ارائه‌ی Source Generators، تولید کدهای تکراری مورد استفاده‌ی در برنامه‌ها است. برای مثال بجای انجام کارهای تکراری مانند پیاده سازی متدهای GetHashCode، ToString و یا حتی یک AutoMapper و یا Serializer، برای تمام کلاس‌های برنامه، Source Generators می‌توانند آن‌ها را به صورت خودکار پیاده سازی کنند و همچنین با هر تغییری در کدهای کلاس‌ها، این پیاده سازی‌ها به صورت خودکار به روز خواهند شد. مزیت این روش نه فقط تولید پویای کدها است، بلکه سبب بهبود کارآیی برنامه هم خواهند شد؛ از این جهت که برای مثال می‌توان اعمالی مانند Serialization را بدون انجام Reflection در زمان اجرا، توسط آن‌ها پیاده سازی کرد.


زمانیکه پروسه‌ی کامپایل برنامه شروع می‌شود، در این بین، به مرحله‌ی جدیدی به نام «تولید کدها» می‌رسد. در این حالت، کامپایلر تمام اطلاعاتی را که در مورد پروژه‌ی جاری در اختیار دارد، به تولید کننده‌ی کد معرفی شده‌ی به آن ارائه می‌دهد. بر اساس این اطلاعات غنی ارائه شده‌ی توسط کامپایلر، تولید کننده‌ی کد، شروع به تولید کدهای جدیدی کرده و آن‌ها را در اختیار ادامه‌ی پروسه‌ی کامپایل، قرار می‌دهد. پس از آن، کامپایلر با این کدهای جدید، همانند سایر کدهای موجود در پروژه رفتار کرده و عملکرد عادی خودش را ادامه می‌دهد.

یک برنامه می‌تواند از چندین Source Generators نیز استفاده کند که روش قرار گرفتن آن‌‌ها را در پروسه‌ی کامپایل، در شکل زیر مشاهده می‌کنید:



Source Generators از یکدیگر کاملا مستقل هستند و اطلاعات آن‌ها Immutable است. یعنی نمی‌توان اطلاعات تولیدی توسط یک Source Generator را در دیگری تغییر داد و تمام فایل‌های تولیدی توسط انواع Source Generators موجود، به پروسه‌ی کامپایل نهایی اضافه می‌شوند. هرچند زمانیکه فایلی توسط یک تولید کننده‌ی کد، به کامپایلر اضافه می‌شود، بلافاصله اطلاعات آن در کل برنامه و IDE و تمام Source Generators موجود دیگر، قابل مشاهده و استفاده است.


مقایسه‌ای بین تولید کننده‌های کد و فناوری IL Weaving

Source Generators، تنها راه و روش تولید کد، نیستند و پیش از آن روش‌هایی مانند استفاده از T4 templates ، Fody ، PostSharp و امثال آن نیز ارائه شده‌است. در ادامه مقایسه‌ای را بین تولید کننده‌های کد و فناوری IL Weaving را که پیشتر در سری AOP در این سایت مطالعه کرده‌اید، مشاهده می‌کنید:
تولید کننده‌های کد:
- تنها می‌توانند فایل‌های جدید را اضافه کنند. یعنی «در حین» پروسه‌ی کامپایل ظاهر می‌شوند و به عنوان یک مکمل، تاثیر گذارند. برای مثال نمی‌توانند محتوای یک خاصیت یا متد از پیش موجود را تغییر دهند. اما می‌توانند هر نوع کد partial ای را «تکمیل» کنند.
- محتوای اضافه شده‌ی توسط یک تولید کننده‌ی کد، بلافاصله توسط Compiler شناسایی شده و بررسی می‌شود و همچنین در Intellisense ظاهر شده و به سادگی قابل دسترسی است. همچنین، قابلیت دیباگ نیز دارد.

IL Weaving:
- می‌توانند bytecode برنامه را تغییر دهند. یعنی «پس از» پروسه‌ی کامپایل ظاهر شده و کدهایی را به اسمبلی نهایی تولید شده اضافه می‌کنند. در این حالت محدودیتی از لحاظ محل تغییر کدها وجود ندارد. برای مثال می‌توان بدنه‌ی یک متد یا خاصیت را بطور کامل بازنویسی کرد و کارکردهایی مانند تزریق کدهای caching و logging را دارند.
- کدهایی که توسط این پروسه اضافه می‌شوند، در حین کدنویسی متداول، قابلیت دسترسی ندارند؛ چون پس از پروسه‌ی کامپایل، به فایل باینری نهایی تولیدی، اضافه می‌شوند. بنابراین قابلیت دیباگ به همراه سایر کدهای برنامه را نیز ندارند. به علاوه چون توسط کامپایلر در حین پروسه‌ی کامپایل، بررسی نمی‌شوند، ممکن است به همراه قطعه کدهای غیرقابل اجرایی نیز باشند و دیباگ آن‌ها بسیار مشکل است.



آینده‌ی Reflection به چه صورتی خواهد شد؟

هرچند Reflection کار تولید کدی را انجام نمی‌دهد، اما یکی از کارهای متداول با آن، یافتن و محاسبه‌ی اطلاعات خواص و فیلدهای اشیاء، در زمان اجرا است و مزیت کار کردن با آن نیز این است که اگر خاصیتی یا فیلدی تغییر کند، نیازی به بازنویسی قسمت‌های پیاده سازی شده‌ی با Reflection نیست. به همین جهت برای مثال تقریبا تمام کتابخانه‌های Serialization، از Reflection برای پیاده سازی اعمال خود استفاده می‌کنند.
امروز، تمام اینگونه عملیات را توسط Source Generators نیز می‌توان انجام داد و این فناوری جدید، قابلیت به روز رسانی خودکار کدهای تولیدی را با کم و زیاد شدن خواص و فیلدهای کلاس‌ها دارد و نمونه‌ای از آن، Source Generator توکار مرتبط با کار با JSON در دات نت 6 است که به شدت سبب بهبود کارآیی برنامه، در مقایسه با استفاده‌ی از Reflection می‌شود؛ چون اینبار تمام محاسبات دقیق مرتبط با Serialization به صورت خودکار در زمان کامپایل برنامه انجام می‌شود و جزئی از خروجی برنامه‌ی نهایی خواهد شد و دیگر نیازی به محاسبه‌ی هرباره‌ی اطلاعات مورد نیاز، در زمان اجرای برنامه نیست.
نمونه‌ای از روش دسترسی به اطلاعات کلاس‌ها و خواص و فیلدهای آن‌ها را در زمان کامپایل برنامه توسط Source Generators، در مثال قسمت بعد، مشاهده خواهید کرد.


وضعیت T4 templates چگونه خواهد شد؟

در سال‌های آغازین ارائه‌ی دات نت، استفاده از T4 templates جهت تولید کدها بسیار مرسوم بود؛ اما با ارائه‌ی Source Generators، این ابزار نیز منسوخ شده در نظر گرفته می‌‌شود.
T4 Templates همانند Source Generators تنها کدها و فایل‌های جدیدی را تولید می‌کنند و توانایی تغییر کدهای موجود را ندارند. اما مشکل مهم آن، داشتن Syntax ای خاص است که توسط اکثر IDEها پشتیبانی نمی‌شود. همچنین عموما اجرای آن‌ها نیز دستی است و برخلاف Source Generators، با تغییرات کدها، به صورت خودکار به روز نمی‌شوند.


تغییرات زبان #C در جهت پشتیبانی از تولید کننده‌های کد

از سال‌های اول ارائه‌ی زبان #C، واژه‌ی کلیدی partial، جهت فراهم آوردن امکان تقسیم کدهای یک کلاس، به چندین فایل، میسر شد که از این قابلیت در فناوری T4 Templates زیاد استفاده می‌شد. اکنون با ارائه‌ی تولید کننده‌های کد، واژه‌ی کلیدی partial را می‌توان به متدها نیز افزود تا پیاده سازی اصلی آن‌ها، در فایلی دیگر، توسط تولید کننده‌های کد انجام شود. تا C# 8.0 امکان افزودن واژه‌ی کلیدی partial به متدهای خصوصی یک کلاس و آن هم از نوع void وجود داشت و در C# 9.0 به متدهای عمومی کلاس‌ها نیز اضافه شده‌است و اکنون این متدها می‌توانند void هم نباشند:
partial class MyType
{
   partial void OnModelCreating(string input); // C# 8.0

   public partial bool IsPet(string input);  // C# 9.0
}

partial class MyType
{
   public partial bool IsPet(string input) =>
     input is "dog" or "cat" or "fish";
}
مطالب
استفاده از dll های دات نت در الکترون
یکی از جذاب‌ترین کارهایی که در کار برنامه نویسی می‌توان انجام داد این است که بتوانیم از کدهای یک زبان دیگر، در زبانی دیگر استفاده کنیم. بسیاری از کاربران این سایت مدت‌هاست که از دات نت استفاده می‌کنند و ممکن است بخواهند از dll‌های آن در الکترون بهره ببرند. در این مقاله بررسی می‌کنیم که چگونه از کدهای دات نت در الکترون استفاده کنیم. ابتدا یک پروژه‌ی Class Library جدید را برای برنامه‌ی فاکتوریل با کد زیر تولید می‌کنیم:
namespace electron_factorial
{
    public class MyMath
    {
        public int Factorial(int number)
        {
            if (number < 2)
                return number;
            return Factorial(number - 1)*number;
        }

        public Task<object> CalcFactorial(object obj)
        {
            return Task.Factory.StartNew(() => Factorial((int) obj) as object);
        }
    }
}
باید توجه داشته باشید متدی که در الکترون صدا میزنید باید دارای آرگومان‌های object و خروجی <Task<Object باشد. برای آشنایی با دستور task مقالات اصول کدنویسی موازی در سایت جاری را مطالعه فرمایید.

سپس کتابخانه تولید شده را به داخل دایرکتوری پروژه انتقال می‌دهیم. پروژه electron-edge را در پروژه صدا می‌زنیم؛ این پروژه که برای الکترون بهینه شده است از روی پروژه Edge فورک شده است که برای خروجی دات نت در node.js تولید شده بود.
npm install electron-edge

حالا کد زیر را می‌نویسیم:
  <script>
  function  myFunction()
    {
      var edge = require('electron-edge');
      var CalcFactorial = edge.func({
           assemblyFile: 'electron-factorial.dll',
           typeName: 'electron_factorial.MyMath',
           methodName: "CalcFactorial"
      });

      document.getElementById("calc").addEventListener("click", function (e) {
           var inputText = document.getElementById("txtnumber").value;
           CalcFactorial(Number(inputText), function (error, result) {
                document.getElementById("factorial").value=result;
           });
      });
    }

    </script>
در ابتدای امر، کلاسی از جنس edge را می‌سازیم و با استفاده از متد func، اطلاعات کتابخانه‌ی دات نت را به عنوان آرگومان وارد می‌کنیم. از این پس CalcFactirial به متد مورد نظر ما در dll اشاره می‌کند. هنگام استفاده از آن هم باید مدنظر داشته باشید با توجه به استفاده از برنامه نویسی موازی، پاسخ تابع به صورت یک callback در اختیار ما قرار می‌گیرد که اولین پارامتر آن خطاست و در صورت رخ دادن، مزین به اطلاعات خطا شده که می‌توانید آن را Throw کنید و در غیر این صورت نال بازگشت داده می‌شود و پارامتر دوم هم در صورتیکه به خطایی برخورد نکنیم، پاسخ تابع را برای ما ارسال خواهد کرد.