Owin چیست ؟ قسمت اول
Mocking چیست؟
فرض کنید برنامهای را داریم که از تعدادی کلاس تشکیل شدهاست. در این بین میخواهیم تعدادی از آنها را به صورت ایزولهی از کل سیستم آزمایش کنیم. البته باید درنظر داشت که این کلاسها در حین اجرای واقعی برنامه، از تعدادی وابستگی خاص در همان سیستم استفاده میکنند. برای مثال کلاسی در این بین برای بررسی میزان اعتبار مالی یک کاربر، نیاز دارد تا با یک وب سرویس خارجی کار کند. اما چون میخواهیم این کلاس را به صورت ایزولهی از کل سیستم آزمایش کنیم، اینبار بجای استفادهی از وابستگی واقعی این کلاس، آن وابستگی را با یک نمونهی تقلیدی یا Mock object در اینجا، جایگزین میکنیم.
بنابراین Mocking به معنای جایگزین کردن یک وابستگی واقعی سیستم که در زمان اجرای آن مورد استفاده قرار میگیرد، با نمونهی تقلیدی مختص زمان آزمایش برنامه، جهت بالابردن سهولت نوشتن آزمونهای واحد است.
دلایل و مزایای استفادهی از Mocking
- یکی از مهمترین دلایل استفادهی از Mocking، کاهش پیچیدگی تنظیمات اولیهی نوشتن آزمونهای واحد است. برای مثال اگر در برنامهی خود از تزریق وابستگیها استفاده میکنید و کلاسی دارای چندین وابستگی تزریق شدهی به آن است، برای آزمایش این کلاس نیاز به تدارک تمام این وابستگیها را خواهید داشت تا بتوان این کلاس را وهله سازی کرد و همچنین برنامه را نیز کامپایل نمود. اما در این بین ممکن است آزمایش متدی در همان کلاس، الزاما از تمام وابستگیهای تزریق شدهی در یک کلاس استفاده نکند. در این حالت، Mocking میتواند تنظیمات پیچیدهی وهله سازی این کلاس را به حداقل برساند.
- Mocking میتواند سبب افزایش سرعت اجرای آزمونهای واحد نیز شود. برای مثال با تقلید سرویسهای خارجی مورد استفادهی در برنامه (هر عملی که از مرزهای سیستم رد شود مانند کار با شبکه، بانک اطلاعاتی، فایل سیستم و غیره)، میتوان میزان I/O و همچنین زمان صرف شدهی به آنرا به حداقل رساند.
- از mock objects میتوان برای رهایی از مشکلات کار با مقادیر غیرمشخص استفاده کرد. برای مثال اگر در کدهای خود از DateTime.Now استفاده میکنید یا اعداد اتفاقی و امثال آن، هربار که آزمونهای واحد را اجرا میکنیم، خروجی متفاوتی را دریافت کرده و بسیاری از آزمونهای نوشته شده با مشکل مواجه میشوند. به کمک mocking میتوان بجای این مقادیر غیرمشخص، یک مقدار ثابت و مشخص را بازگشت دهد.
- چون به سادگی میتوان mock objects را تهیه کرد، میتوان کار توسعه و آزمایش برنامه را پیش از به پایان رسیدن پیاده سازی اصلی سرویسهای مدنظر، همینقدر که اینترفیس آن سرویس مشخص باشد، شروع کرد که میتواند برای کارهای تیمی بسیار مفید باشد.
- اگر وابستگی مورد استفاده ناپایدار و یا غیرقابل پیش بینی است، میتوان توسط mocking به یک نمونهی قابل پیش بینی و پایدار مخصوص آزمونهای برنامه رسید.
- اگر وابستگی خارجی مورد استفاده به ازای هر بار استفاده، هزینهای را شارژ میکند، میتوان توسط mocking، هزینهی آزمونهای برنامه را کاهش داد.
Unit test چیست؟
بدیهی است در کنار آزمایش ایزولهی قسمتهای مختلف برنامه توسط mocking، باید کل برنامه را جهت بررسی دستیابی به نتایج واقعی نیز آزمایش کرد که به این نوع آزمونها، آزمون یکپارچگی (Integration Tests)، API Tests ،UI Tests و غیره میگویند که در کنار Unit tests ما حضور خواهند داشت. بنابراین اکنون این سؤال مطرح میشود که یک Unit چیست؟
در برنامهای که از چندین کلاس تشکیل میشود، به یک کلاس، یک Unit گفته میشود. همچنین اگر در این سیستم، دو یا چند کلاس با هم کار میکنند (کلاسی که از چندین وابستگی استفاده میکند)، اینها با هم نیز یک Unit را تشکیل دهند. بنابراین تعریف Unit بستگی به نحوهی درک عملکرد یک سیستم و تعامل اجزای آن با هم دارد.
واژههای متناظر با Mock objects
در حین مطالعهی منابع مرتبط با آزمونهای واحد ممکن است با این واژههای تقریبا مشابه مواجه شوید: fakes ،stubs ،dummies و mocks. اما تفاوت آنها در چیست؟
- Fakes در حقیقت یک نمونه پیاده سازی واقعی، اما غیرمناسب محیط واقعی و اصلی پروژهاست. برای نمونه EF Core به همراه یک نمونه in-memory database هم هست که دقیقا با مفهوم Fakes تطابق دارد.
- از Dummies صرفا جهت تهیهی پارامترهای مورد نیاز برای اجرای یک آزمایش استفاده میشوند. این پارامترها، هیچگاه در آزمایشهای انجام شده مورد استفاده قرار نمیگیرند.
- از Stubs برای ارائهی پاسخهایی مشخص به فراخوانها استفاده میشود. برای مثال یک متد یا خاصیت، دقیقا چه چیزی را باید بازگشت دهند.
- از Mocks برای بررسی تعامل اجزای مختلف در حال آزمایش استفاده میشود. آیا متدی یا خاصیتی مورد استفاده قرار گرفتهاست یا خیر؟
باید درنظر داشت که زمانیکه یک شیء Mock را توسط کتابخانهی Moq تهیه میکنیم، هر سه مفهوم stubs ،dummies و mocks را با هم به همراه دارد. به همین جهت در این سری زمانیکه به یک mock object اشاره میشود، هر سه مفهوم مدنظر هستند.
واژهی دیگری که ممکن است در این گروه زیاد مشاهده شود، «Test double» نام دارد که ترکیب هر 4 مورد fakes ،stubs ،dummies و mocks میباشد. در کل هر زمانیکه یک شیء مورد استفادهی در زمان اجرای برنامه را جهت آزمایش سادهتر آن جایگزین میکنید، یک Test double را ایجاد کردهاید.
بررسی ساختار برنامهای که میخواهیم آنرا آزمایش کنیم
در این سری قصد داریم یک برنامهی وام دهی را آزمایش کنیم که قسمتهای مختلف آن دارای وابستگیهای خاصی میباشند. ساختار این برنامه را در ادامه مشاهده میکنید:
موجودیتهای برنامهی وام دهی
namespace Loans.Entities { public class Applicant { public int Id { set; get; } public string Name { set; get; } public int Age { set; get; } public string Address { set; get; } public decimal Salary { set; get; } } }
namespace Loans.Entities { public class LoanProduct { public int Id { set; get; } public string ProductName { set; get; } public decimal InterestRate { set; get; } } }
namespace Loans.Entities { public class LoanApplication { public int Id { set; get; } public LoanProduct Product { set; get; } public LoanAmount Amount { set; get; } public Applicant Applicant { set; get; } public bool IsAccepted { set; get; } } public class LoanAmount { public string CurrencyCode { get; set; } public decimal Principal { get; set; } } }
مدلهای برنامهی وام دهی
namespace Loans.Models { public class IdentityVerificationStatus { public bool Passed { get; set; } } }
سرویسهای برنامهی وام دهی
using Loans.Models; namespace Loans.Services.Contracts { public interface IIdentityVerifier { void Initialize(); bool Validate(string applicantName, int applicantAge, string applicantAddress); void Validate(string applicantName, int applicantAge, string applicantAddress, out bool isValid); void Validate(string applicantName, int applicantAge, string applicantAddress, ref IdentityVerificationStatus status); } }
namespace Loans.Services.Contracts { public interface ICreditScorer { int Score { get; } void CalculateScore(string applicantName, string applicantAddress); } }
using System; using Loans.Entities; using Loans.Services.Contracts; namespace Loans.Services { public class LoanApplicationProcessor { private const decimal MinimumSalary = 1_500_000_0; private const int MinimumAge = 18; private const int MinimumCreditScore = 100_000; private readonly IIdentityVerifier _identityVerifier; private readonly ICreditScorer _creditScorer; public LoanApplicationProcessor( IIdentityVerifier identityVerifier, ICreditScorer creditScorer) { _identityVerifier = identityVerifier ?? throw new ArgumentNullException(nameof(identityVerifier)); _creditScorer = creditScorer ?? throw new ArgumentNullException(nameof(creditScorer)); } public bool Process(LoanApplication application) { application.IsAccepted = false; if (application.Applicant.Salary < MinimumSalary) { return application.IsAccepted; } if (application.Applicant.Age < MinimumAge) { return application.IsAccepted; } _identityVerifier.Initialize(); var isValidIdentity = _identityVerifier.Validate( application.Applicant.Name, application.Applicant.Age, application.Applicant.Address); if (!isValidIdentity) { return application.IsAccepted; } _creditScorer.CalculateScore(application.Applicant.Name, application.Applicant.Address); if (_creditScorer.Score < MinimumCreditScore) { return application.IsAccepted; } application.IsAccepted = true; return application.IsAccepted; } } }
using System; using Loans.Models; using Loans.Services.Contracts; namespace Loans.Services { public class IdentityVerifierServiceGateway : IIdentityVerifier { public DateTime LastCheckTime { get; private set; } public void Initialize() { // Initialize connection to external service } public bool Validate(string applicantName, int applicantAge, string applicantAddress) { Connect(); var isValidIdentity = CallService(applicantName, applicantAge, applicantAddress); LastCheckTime = DateTime.Now; Disconnect(); return isValidIdentity; } private void Connect() { // Open connection to external service } private bool CallService(string applicantName, int applicantAge, string applicantAddress) { // Make call to external service, interpret the response, and return result return false; // Simulate result for demo purposes } private void Disconnect() { // Close connection to external service } public void Validate(string applicantName, int applicantAge, string applicantAddress, out bool isValid) { throw new NotImplementedException(); } public void Validate(string applicantName, int applicantAge, string applicantAddress, ref IdentityVerificationStatus status) { throw new NotImplementedException(); } } }
هدف از این برنامه، درخواست یک وام جدید است. Application در اینجا به معنای درخواست یا فرم جدید است و Applicant نیز شخصی است که این درخواست را دادهاست.
در اینجا بیشتر تمرکز ما بر روی کلاس LoanApplicationProcessor است که دارای دو وابستگی تزریق شدهی به آن نیز میباشد:
public LoanApplicationProcessor( IIdentityVerifier identityVerifier, ICreditScorer creditScorer) { _identityVerifier = identityVerifier ?? throw new ArgumentNullException(nameof(identityVerifier)); _creditScorer = creditScorer ?? throw new ArgumentNullException(nameof(creditScorer)); }
تمام این منطق نیز در متد Process آن قابل مشاهدهاست که هدف اصلی آن، بررسی قابل پذیرش بودن درخواست یک وام جدید است.
نوشتن اولین تست، برای برنامهی وام دهی
در اولین تصویر این قسمت، پروژهی class library دومی را نیز به نام Loans.Tests مشاهده میکنید. فایل csproj آن به صورت زیر برای کار با MSTest تنظیم شدهاست:
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>netcoreapp2.2</TargetFramework> </PropertyGroup> <ItemGroup> <ProjectReference Include="..\Loans\Loans.csproj" /> </ItemGroup> <ItemGroup> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.3.0" /> <PackageReference Include="MSTest.TestAdapter" Version="2.0.0" /> <PackageReference Include="MSTest.TestFramework" Version="2.0.0" /> </ItemGroup> </Project>
اکنون اولین آزمون واحد ما در کلاس جدید LoanApplicationProcessorShould چنین شکلی را پیدا میکند:
using Loans.Entities; using Loans.Services; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace Loans.Tests { [TestClass] public class LoanApplicationProcessorShould { [TestMethod] public void DeclineLowSalary() { var product = new LoanProduct {Id = 99, ProductName = "Loan", InterestRate = 5.25m}; var amount = new LoanAmount {CurrencyCode = "Rial", Principal = 2_000_000_0}; var applicant = new Applicant {Id = 1, Name = "User 1", Age = 25, Address = "This place", Salary = 1_100_000_0}; var application = new LoanApplication {Id = 42, Product = product, Amount = amount, Applicant = applicant}; var processor = new LoanApplicationProcessor(null, null); processor.Process(application); Assert.IsFalse(application.IsAccepted); } } }
در این آزمایش، شخص درخواست کننده، حقوق کمی دارد و میخواهیم بررسی کنیم که آیا LoanApplicationProcessor میتواند آنرا بر اساس مقدار MinimumSalary، رد کند یا خیر؟
public class LoanApplicationProcessor { private const decimal MinimumSalary = 1_500_000_0;
در حین وهله سازی LoanApplicationProcessor، دو وابستگی آن به null تنظیم شدهاند؛ چون میدانیم که بررسی MinimumSalary پیش از سایر بررسیها صورت میگیرد و اساسا در این آزمایش، نیازی به این وابستگیها نداریم.
اما اگر سعی در اجرای این آزمایش کنیم (برای مثال با اجرای دستور dotnet test در خط فرمان)، آزمایش اجرا نشده و با استثنای زیر مواجه میشویم:
Test method Loans.Tests.LoanApplicationProcessorShould.DeclineLowSalary threw exception: System.ArgumentNullException: Value cannot be null. Parameter name: identityVerifier
public LoanApplicationProcessor( IIdentityVerifier identityVerifier, ICreditScorer creditScorer) { _identityVerifier = identityVerifier ?? throw new ArgumentNullException(nameof(identityVerifier)); _creditScorer = creditScorer ?? throw new ArgumentNullException(nameof(creditScorer)); }
نصب کتابخانهی Moq جهت برآورده کردن وابستگیهای کلاس LoanApplicationProcessor
در این آزمایش چون وجود وابستگیهای در سازندهی کلاس، برای ما اهمیتی ندارند و همچنین ذکر آنها نیز الزامی است، میخواهیم توسط کتابخانهی Moq، دو نمونهی تقلیدی از آنها را تهیه کرده (همان dummies که پیشتر معرفی شدند) و جهت برآورده کردن بررسی صورت گرفتهی در سازندهی کلاس LoanApplicationProcessor، آنها را ارائه کنیم.
کتابخانهی بسیار معروف Moq، با پروژههای مبتنی بر NETFramework 4.5. و همچنین NETStandard 2.0. به بعد سازگار است و برای نصب آن، میتوان یکی از دو دستور زیر را صادر کرد:
> dotnet add package Moq > Install-Package Moq
اما چرا کتابخانهی Moq؟
کتابخانهی Moq این اهداف را دنبال میکند: سادهاست، به شدت کاربردیاست و همچنین strongly typed است. این کتابخانه سورس باز بوده و تعداد بار دانلود بستهی نیوگت آن میلیونی است.
پس از نصب آن، اولین آزمایشی را که نوشتیم، به صورت زیر اصلاح میکنیم:
using Loans.Entities; using Loans.Services; using Loans.Services.Contracts; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; namespace Loans.Tests { [TestClass] public class LoanApplicationProcessorShould { [TestMethod] public void DeclineLowSalary() { var product = new LoanProduct {Id = 99, ProductName = "Loan", InterestRate = 5.25m}; var amount = new LoanAmount {CurrencyCode = "Rial", Principal = 2_000_000_0}; var applicant = new Applicant {Id = 1, Name = "User 1", Age = 25, Address = "This place", Salary = 1_100_000_0}; var application = new LoanApplication {Id = 42, Product = product, Amount = amount, Applicant = applicant}; var mockIdentityVerifier = new Mock<IIdentityVerifier>(); var mockCreditScorer = new Mock<ICreditScorer>(); var processor = new LoanApplicationProcessor(mockIdentityVerifier.Object, mockCreditScorer.Object); processor.Process(application); Assert.IsFalse(application.IsAccepted); } } }
کار با ذکر new Mock شروع شده و آرگومان جنریک آنرا از نوع وابستگیهایی که نیاز داریم، مقدار دهی میکنیم. سپس خاصیت Object آن، امکان دسترسی به این شیء تقلید شده را میسر میکند.
اکنون اگر مجددا این آزمون واحد را اجرا کنیم، مشاهده خواهیم کرد که بجای صدور استثناء، با موفقیت به پایان رسیدهاست:
گاهی از اوقات جایگزین کردن یک وابستگی null با نمونهی Mock آن کافی نیست
در مثالی که بررسی کردیم، اشیاء mock، کار برآورده کردن نیازهای ابتدایی آزمایش را انجام داده و سبب اجرای موفقیت آمیز آن شدند؛ اما همیشه اینطور نیست:
using Loans.Entities; using Loans.Services; using Loans.Services.Contracts; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; namespace Loans.Tests { [TestClass] public class LoanApplicationProcessorShould { [TestMethod] public void Accept() { var product = new LoanProduct {Id = 99, ProductName = "Loan", InterestRate = 5.25m}; var amount = new LoanAmount {CurrencyCode = "Rial", Principal = 2_000_000_0}; var applicant = new Applicant {Id = 1, Name = "User 1", Age = 25, Address = "This place", Salary = 1_500_000_0}; var application = new LoanApplication {Id = 42, Product = product, Amount = amount, Applicant = applicant}; var mockIdentityVerifier = new Mock<IIdentityVerifier>(); var mockCreditScorer = new Mock<ICreditScorer>(); var processor = new LoanApplicationProcessor(mockIdentityVerifier.Object, mockCreditScorer.Object); processor.Process(application); Assert.IsTrue(application.IsAccepted); } } }
اگر این آزمایش را اجرا کنیم، با شکست مواجه خواهد شد. علت اینجا است که هرچند در حال استفادهی از دو mock object به عنوان وابستگیهای مورد نیاز هستیم، اما تنظیمات خاصی را بر روی آنها انجام ندادهایم و به همین جهت خروجی مناسبی را در اختیار LoanApplicationProcessor قرار نمیدهند. برای مثال مرحلهی بعدی بررسی اعتبار شخص در کلاس LoanApplicationProcessor، فراخوانی سرویس identityVerifier و متد Validate آن است که خروجی آن بر اساس کدهای فعلی، همیشه false است:
_identityVerifier.Initialize(); var isValidIdentity = _identityVerifier.Validate( application.Applicant.Name, application.Applicant.Age, application.Applicant.Address);
کدهای کامل این قسمت را از اینجا میتوانید دریافت کنید: MoqSeries-01.zip
- شناسایی منابع
- بکارگیری منابع از طریق نمایش آنها (منابع وب)
- پیامهای خودتوصیفی
- ابررسانه بعنوان قلب تپنده موقعیت برنامه
- درگیر نکردن برنامه “
- توزیع (HTTP , Feeds)
- ترکیب (Hypermedia , Mashups)
- امنیت (Open ID, SSL)
- قابلیت انتقال داده (XML,RDF)
- قابلیت نمایش داده (ATOM, JSON)
- متدهای انتقال (REST, HTTP, Bit Torrent)
- هر چیزی یک منبع است.
- هر منبعی یک تمثیل دارد.
- هر منبعی یک نام بخصوص دارد.
- انتقال موقعیت نیازمند کشف و شهود (Discovery) است.
- پروتکل شبکه پایه WOA میباشد
- اطلاعات در قالب منابع (Resources) نمایش مییابند.
- منابع توسط URIها شناخته میشوند.
- منابع از طریق HTTP اداره میشوند.
- معاهدات به صورت ضمنی در نمایش منابع میباشند.
- رابطها بطور کلی عام هستند.
- ساده سازی توسعه پذیری، مقیاس پذیری
- کاهش زمان توسعه ویژگیهای جدید
- کاهش زمان مهندسی مورد نیاز برای یکپارچه سازی
- سازنده فرصتهایی جدید برای mash-ups و دیگر داستانهای غیرقابل پیش بینی کاربری
- اما وضعیت ارتباطی کلاینتها و سرورها در WOA چگونه است ؟
- سرویسها وابسته به دیگر سرویسها هستند.
- ارتباطات از طریق HTTP صورت میگیرد.
- کلاینتها حکم منبع و سرویس دهی به دیگر کلاینتها را دارند.
- مقیاس پذیری ، توسعه پذیری == اتصالات داخی
بعنوان مثال میتوان با ترکیب تصاویر و آدرسهای مختلف دانشگاههای تهران، یک map Mashup درست کرد.
برای Photo Mashup ابزار Color Picker هم هست که امکان جستجوی تصاویر را بر اساس رنگ فراهم میکند و از سرویس اشتراک گذاری عکس Flickr استفاده میکند که در این آدرس قابل استفاده است.
معماری Mashup هم مثل معماری MVC (البته با تفاوتهای فاحش) سه لایهای است :
لایه نمایش / تعامل کاربر (همان رابط کاربری است)
تکنولوژیها : HTML/XHTML, CSS, Javascript, Asynchronous JS and Xml (Ajax).
وب سرویسها : عملکرد محصول از طریق سرویسهای API هم قابل دسترسی است
تکنولوژیها : XMLHTTPRequest, XML-RPC, JSON-RPC, SOAP, REST
داده : فراهم آوردن امکان ارسال ، مرتب سازی و دریافت داده
تکنولوژیها : XML , JSON , KML
از نظر معماری Mashup دارای 2 سبک است : الف) مبتنی بر وب – ب) مبتنی بر سرور
در ادامه با هم نمونه ای از استقرار معماری وب گرا WOA را در سازمان، بصورت شماتیک میبینیم. با هم مشاهده میکنیم با این پیاده سازی، موانع سر راه ما کاهش پیدا میکنند و سرعت یکپارچگی افزایش پیدا میکند. بدین صورت که میتوان از قدرت شبکه جهانی وب در جهت انتقال محتوای مورد نیازمان به هر جا و در هر زمانی بهره جست.
شاید برای شما سوال پیش بیاید که ما در معماری وب گرا بحث میکردیم، اصلا چرا وارد مفهوم Mashup شدیم؟
بهعبارت فنیتر چرا معماری وب گرا (WOA) برای Mashups اهمیت دارد ؟
پاسخ یک کلمه است : REST . همانطور که بالاتر نیز اشاره کردم، Mashup از REST بهره میبرد. به منظور افزایش اطلاعات در رابطه با REST باید گفت Roy Fielding آنرا بنیان نهادهاست. میخواهید او را بهتر معرفی کنم؟ وی یکی از خالقان HTTP است و مگر میتوان وب را بدون HTTP فرض کرد که مهمترین پروتکل انتقال ابر متن در جهان و پروتکل زیربنایی وب است؟!
REST به خوبی با معماری اینترنت عجین شده است! بپرسید چرا؟ چون پروتکل اصلی اینترنت HTTP است و هر دوی اینها از یک ذهن نشات گرفته و او کسی نیست جز Roy Fielding. اما باید بگویم REST یک استاندارد نیست؛ با وجود سادگی بسیار زیاد، تنها یک سبک استفاده از HTTP است.
REST همچنین از متدهای اختصاصی HTTP نظیر GET, PUT , POST , DELETE در بالای یک URL استفاده میکند تا نشان دهد چه رویدادی رخ میدهد.
در پایان گفتهها در رابطه با REST باید بگویم ATOM همان REST است. منظورم از ATOM ویرایشگر معروف متنی نیست که برای نوشتن کدهای برنامه نویسی استفاده قرار میگیرد؛ آنرا غالبا به شکل Atom مینویسند چرا که مخفف چند کلمه نیست و یک کلمه خاص است اما ATOM یک استاندارد وب به زبان XML است که برای خوراک وب بعنوان جایگزینی برای RSS استفاده میشود. ATOM را با AtomPub یا APP اشتباه نگیرید؛ چرا که APP پروتکل انتشاری است مبتنی بر پروتکل انتقال ابرمتن (HTTP) و برای به روزرسانی محتوی وب مورد استفاده قرار میگیرد.
در ادامه مباحث دررابطه با معماری وب گرا باید گفت WOA امروزه بعنوان مدل حاکم برنامههای تحت شبکه مطرح است. اما متاسفانه فروشندگان بزرگی در پشت آن حضور ندارند به همین دلیل آنچنان که باید عمومیت نیافته است. WOA همچنان میتواند بیشترین سود حاصل را از طریق شبکه فراهم کند. شاید بتوان گفت کوتاهترین مسیر برای رسیدن به چنین نتیجهای همین معماری وب گرا است.
فرمول جالبی هم برای تعریف وب ارائه شدهاست که با هم میبینیم :
HTTP + URIs = Web
ظرافت فرمول بالا به اهمیت پروتکل زیربنایی وب یعنی HTTP اشاره دارد. URI هم مجموعهای از رشتههاست که برای شناسایی یک منبع خاص تحت وب به کار میروند. در شکل زیر رابطه بین URI , URN , URL را بررسی میکنیم. URI تشکیل شدهاست از URL و URN .URL متد دسترسی به منبع را مشخص میکند، در حالیکه URN تنها مشخص کننده نام منبع میباشد و هیچگونه روشی را برای دسترسی به ما ارائه نمیدهد. بعنوان مثال یک شماره ISBN کتاب، یک نوع URN است.
مسائل سی شارپ
چه نوع محیط کاری را بیشتر ترجیح میدهید؟
سؤالی از طریق ایمیل از من پرسیده شده که ترجیح میدهم آنرا به صورت باز در اینجا پاسخ دهم. اگر فرض کنیم همین فردا مجبور شویم برای عمدهی کارهای خود لایسنس تهیه کنیم، آیا میتوان از ابزارهای موجود دات نت در یک شرکت تازه تاسیس (startup) استفاده کرد؟ آیا هزینهی کار با ویندوز واقعا بالا است؟ آیا ...
همچنین عموم تازه واردان به این جمع هم از لیست امکانات رایگان مهیا که فقط پس از خرید یک لایسنس اولیه ویندوز در اختیار آنها خواهند بود، بیاطلاع هستند. بنابراین بد نیست اینها را با هم لیست کنیم.
سؤال: هزینه استفاده از دات نت فریم ورک چقدر است؟
پاسخ: رایگان است! از زمان ارائه ویندوز سرور 2003 به بعد، دات نت فریم ورک به عنوان یکی از کامپوننتهای اصلی ویندوز عرضه میشود و هر شخصی که مجوز اصلی استفاده از ویندوز را خریده باشد، به صورت خودکار مجوز استفاده از دات نت فریم ورک را هم خواهد داشت و نیازی نیست بابت آن هزینهی خاصی را متقبل شود. برای مثال ویندوز سرور 2003 ، دات نت 1.1 سرخود است و ویندوز 7 و ویندوز سرور 2008 ، دات نت سه و نیم سرخود هستند.
سؤال: آیا برای توسعهی دات نت حتما نیاز است تا ویژوال استودیوی چند هزار دلاری را خرید؟!
پاسخ: خیر! ویژوال استودیو، نسخههای مختلفی دارد و حتما نیازی نیست تا از نسخهی ultimate آن استفاده کنید. برای مثال نسخهی Express آن که توسط خود مایکروسافت ارائه شده، رایگان است (+). مهمترین تفاوت آن با نسخهی ultimate در این است که افزونه پذیر نیست و این مورد شاید برای خیلیها اصلا اهمیتی نداشته باشد چون عموما افزونههای بد نوشته شده، باعث ناپایداری IDE میشوند یا مثلا نسخهی ultimate به همراه MSTests جهت انجام سادهتر unit testing ارائه شده که در نسخهی Express وجود ندارد، این هم مهم نیست چون فریم ورکهای سورس باز آزمون واحد دیگری مانند Nunit ، MBUnit و غیره هم وجود دارند که اصلا نیازی به هیچ IDE خاصی جهت کار ندارند و مسایلی از این دست. یا برای سورس کنترل میشود از SVN ، Git ، مرکوریال و غیره هم همیشه استفاده کرد. اینها هم مستقل هستند از نوع IDE مورد استفاده.
همچنین یک گروه مستقل، IDE دیگری را به نام SharpDevelop تهیه کردهاند که بسیار با کیفیت بوده و از همه مهمتر سورس باز است و رایگان. خیلیها از کنترلهای این IDE در پروژههای خودشون استفاده میکنند (مثل syntax highlighting همراه آن و غیره)
در کنار تمام اینها، هیچ وقت دقت کردهاید که در پوشه دات نت نصب شده در ویندوز چه چیزهایی یافت میشوند؟! مثلا به آدرس C:\Windows\Microsoft.NET\Framework\v4.0.30319 مراجعه کنید. فایل csc.exe همان کامپایلر خط فرمان سی شارپ است. کاری هم که IDE ها انجام می دهند این است که لیست فایلهای شما رو به صورت آرگومان به این برنامه ارسال میکنند. این اتوماسیون به صورت دستی هم میسر است. IDE شما میشود مثلا برنامه رایگان notepad++ ایی که syntax highlighting تمام زبانهای دات نتی را پشتیبانی میکند. سادهترین سیستم build شما یک فایل bat خواهد بود که csc.exe را مدیریت میکند.
علاوه بر تمام اینها، MonoDevelop را هم اضافه کنید. این IDE ، نسخهی ویندوزی هم دارد.
سؤال: من شنیدم دات نت فقط با SQL Server کار میکنه. این هم که گرونه؟!
پاسخ: خیر! نسخهی رایگان SQL server به نام SQL Server express هم موجود است و در نسخهی 2008 R2 آن محدودیت حجم بانک اطلاعاتی آن به 10 گیگ رسیده که برای اکثر کارها تا چند سال کافی است (+).
ضمنا قبلا در مورد لیست بانکهای اطلاعاتی قابل استفاده توسط دات نت فریم ورک مطلب نوشتم و در سایت موجود است. بنابراین دات نت اصلا به SQL Server محدود نیست (+).
سؤال: دات نت سورس بسته است! نه این اصلا خوب نیست؛ آینده نداره!
پاسخ: خیر. سورس کامل دات نت فریم ورک تحت مجوزهای MS-PL و MS-RSL چندسالی هست که منتشر شده و این مجوز (MS-PL) جزو مجوزهای معتبر و پذیرفته شده سورس باز است (+).
لینک دریافت
خبر مرتبط
ضمنا کارهای سورس باز مایکروسافت به این یک قلم ختم نمیشود. برای مثال به سایت CodePlex مراجعه کنید تا سورس کامل ASP.NET MVC نگارش 3 را دریافت کنید(+)، همینطور مجموعه کنترلهای WPF و Silverlight و غیرهای که تهیه کردهاند (+) و بسیاری موارد دیگر.
سؤال: دات نت که فقط روی ویندوز اجرا میشه. نه؛ این خوب نیست!
پاسخ: خیر! پروژهای سابقا تحت عنوان Mono وجود دارد/داشت (+) که توسط شرکت ناول اداره میشد و کار آن انتقال دات نت به لینوکس و سایر سکوهای کاری بود. پس از فروخته شدن ناول، این پروژه به ظاهر متوقف شد، اما تیم اصلی آن تحت نام دیگری به نام زاماریان (+) دوباره شروع به کار کرده و جالب اینجا است که تا دات نت 4 را هم تحت لینوکس پشتیبانی میکند(+). جهت اطلاع ASP.NET رو به صورت کامل میتونید تحت لینوکس اجرا کنید (+). همچنین سایر موارد پشتیبانی شده رو.
سؤال: وضعیت بازار کار دات نت در ایران چطور است؟
پاسخ: آقای محبی برنامهای رو درست کردهاند به نام کارویس که من مدتی است مشترک فید آن هستم تا حدودا از نیازهای عمومی بازار کار برنامه نویسی ایران اطلاع کسب کنم (+). نکتهی جالبی که در فید این برنامه مشخص است، درخواست بالای نیاز به برنامه نویس دات نت در کشور است. بالای 80 درصد آگهیها نیاز به برنامه نویس دات نت دارند.
در کنار تمام این مباحث، بحث «هزینه یادگیری و آموزش» را هم اضافه کنید. شاید یکی بیاد بگه CPP فلان، اون یکی بهمان! ولی این سؤالات هم برای من نوعی که تیم گوگل کروم نوشته شده با CPP رو مدیریت نمیکنم (و به قول اونطرف آبیها یک Average Joe هستم!) مهم هستند:
- چندتا کتاب فارسی آموزشی خوب در این زمینه در کشور موجود است. من یادم میاد اولین کتاب VC منتشر شده در کشور پس از 450 صفحه به شما یاد میداد چطور با MFC دکمه به صفحه اضافه کنید، چطور منو درست کنید و همین! این شد برنامه نویسی CPP!
- چند عدد انجمن رفع اشکال فعال را که تاریخ آخرین به روز رسانی و پرسش و پاسخ آنها مثلا دیروز بوده را در مورد زبان xyz میتوان یافت؟
- اگر به مشکل برخوردم، کسی هست به داد من برسه؟ چه زمانی؟! مثلا هفته بعد یا تا آخر امروز؟
- چندتا وبلاگ فعال در این زمینه موجود است؟ آیا هستند کسانی که در این زمینهها فعالانه مطلب منتشر کنند؟ اطلاع رسانی کنند؟
- اگر کارمند برنامه نویس شرکتی امروز قهر کرد، مدیر بخش توسعه تا چه زمانی میتونه یک نفر رو جایگزین اون کنه؟ مثلا تا آخر ماه یا تا آخر سال؟! اون هم با چه کیفیتی؟ با چه دستمزدی؟
و اینجا است که وضعیت دات نت در ایران بسیار مطلوبتر از موارد مشابه به نظر میرسد. از نظر تعداد کتاب فارسی مهیا، تعداد انجمن، تعداد وبلاگ فعال و غیره.
سؤالی از طریق ایمیل از من پرسیده شده که ترجیح میدهم آنرا به صورت باز در اینجا پاسخ دهم. اگر فرض کنیم همین فردا مجبور شویم برای عمدهی کارهای خود لایسنس تهیه کنیم، آیا میتوان از ابزارهای موجود دات نت در یک شرکت تازه تاسیس (startup) استفاده کرد؟ آیا هزینهی کار با ویندوز واقعا بالا است؟ آیا ...
همچنین عموم تازه واردان به این جمع هم از لیست امکانات رایگان مهیا که فقط پس از خرید یک لایسنس اولیه ویندوز در اختیار آنها خواهند بود، بیاطلاع هستند. بنابراین بد نیست اینها را با هم لیست کنیم.
سؤال: هزینه استفاده از دات نت فریم ورک چقدر است؟
پاسخ: رایگان است! از زمان ارائه ویندوز سرور 2003 به بعد، دات نت فریم ورک به عنوان یکی از کامپوننتهای اصلی ویندوز عرضه میشود و هر شخصی که مجوز اصلی استفاده از ویندوز را خریده باشد، به صورت خودکار مجوز استفاده از دات نت فریم ورک را هم خواهد داشت و نیازی نیست بابت آن هزینهی خاصی را متقبل شود. برای مثال ویندوز سرور 2003 ، دات نت 1.1 سرخود است و ویندوز 7 و ویندوز سرور 2008 ، دات نت سه و نیم سرخود هستند.
سؤال: آیا برای توسعهی دات نت حتما نیاز است تا ویژوال استودیوی چند هزار دلاری را خرید؟!
پاسخ: خیر! ویژوال استودیو، نسخههای مختلفی دارد و حتما نیازی نیست تا از نسخهی ultimate آن استفاده کنید. برای مثال نسخهی Express آن که توسط خود مایکروسافت ارائه شده، رایگان است (+). مهمترین تفاوت آن با نسخهی ultimate در این است که افزونه پذیر نیست و این مورد شاید برای خیلیها اصلا اهمیتی نداشته باشد چون عموما افزونههای بد نوشته شده، باعث ناپایداری IDE میشوند یا مثلا نسخهی ultimate به همراه MSTests جهت انجام سادهتر unit testing ارائه شده که در نسخهی Express وجود ندارد، این هم مهم نیست چون فریم ورکهای سورس باز آزمون واحد دیگری مانند Nunit ، MBUnit و غیره هم وجود دارند که اصلا نیازی به هیچ IDE خاصی جهت کار ندارند و مسایلی از این دست. یا برای سورس کنترل میشود از SVN ، Git ، مرکوریال و غیره هم همیشه استفاده کرد. اینها هم مستقل هستند از نوع IDE مورد استفاده.
همچنین یک گروه مستقل، IDE دیگری را به نام SharpDevelop تهیه کردهاند که بسیار با کیفیت بوده و از همه مهمتر سورس باز است و رایگان. خیلیها از کنترلهای این IDE در پروژههای خودشون استفاده میکنند (مثل syntax highlighting همراه آن و غیره)
در کنار تمام اینها، هیچ وقت دقت کردهاید که در پوشه دات نت نصب شده در ویندوز چه چیزهایی یافت میشوند؟! مثلا به آدرس C:\Windows\Microsoft.NET\Framework\v4.0.30319 مراجعه کنید. فایل csc.exe همان کامپایلر خط فرمان سی شارپ است. کاری هم که IDE ها انجام می دهند این است که لیست فایلهای شما رو به صورت آرگومان به این برنامه ارسال میکنند. این اتوماسیون به صورت دستی هم میسر است. IDE شما میشود مثلا برنامه رایگان notepad++ ایی که syntax highlighting تمام زبانهای دات نتی را پشتیبانی میکند. سادهترین سیستم build شما یک فایل bat خواهد بود که csc.exe را مدیریت میکند.
سؤال: من شنیدم دات نت فقط با SQL Server کار میکنه. این هم که گرونه؟!
پاسخ: خیر! نسخهی رایگان SQL server به نام SQL Server express هم موجود است و در نسخهی 2008 R2 آن محدودیت حجم بانک اطلاعاتی آن به 10 گیگ رسیده که برای اکثر کارها تا چند سال کافی است (+).
ضمنا قبلا در مورد لیست بانکهای اطلاعاتی قابل استفاده توسط دات نت فریم ورک مطلب نوشتم و در سایت موجود است. بنابراین دات نت اصلا به SQL Server محدود نیست (+).
سؤال: دات نت سورس بسته است! نه این اصلا خوب نیست؛ آینده نداره!
پاسخ: خیر. سورس کامل دات نت فریم ورک تحت مجوز MS-PL چندسالی هست که منتشر شده و این مجوز جزو مجوزهای معتبر و پذیرفته شده سورس باز است (+).
لینک دریافت
خبر مرتبط
ضمنا کارهای سورس باز مایکروسافت به این یک قلم ختم نمیشود. برای مثال به سایت CodePlex مراجعه کنید تا سورس کامل ASP.NET MVC نگارش 3 را دریافت کنید(+)، همینطور مجموعه کنترلهای WPF و Silverlight و غیرهای که تهیه کردهاند (+) و بسیاری موارد دیگر.
سؤال: دات نت که فقط روی ویندوز اجرا میشه. نه؛ این خوب نیست!
پاسخ: خیر! پروژهای سابقا تحت عنوان Mono وجود دارد/داشت (+) که توسط شرکت ناول اداره میشد و کار آن انتقال دات نت به لینوکس و سایر سکوهای کاری بود. پس از فروخته شدن ناول، این پروژه به ظاهر متوقف شد، اما تیم اصلی آن تحت نام دیگری به نام زاماریان (+) دوباره شروع به کار کرده و جالب اینجا است که تا دات نت 4 را هم تحت لینوکس پشتیبانی میکند(+). جهت اطلاع ASP.NET رو به صورت کامل میتونید تحت لینوکس اجرا کنید (+). همچنین سایر موارد پشتیبانی شده رو.
سؤال: وضعیت بازار کار دات نت در ایران چطور است؟
پاسخ: آقای محبی برنامهای رو درست کردهاند به نام کارویس که من مدتی است مشترک فید آن هستم تا حدودا از نیازهای عمومی بازار کار برنامه نویسی ایران اطلاع کسب کنم (+). نکتهی جالبی که در فید این برنامه مشخص است، درخواست بالای نیاز به برنامه نویس دات نت در کشور است. بالای 80 درصد آگهیها نیاز به برنامه نویس دات نت دارند.
در کنار تمام این مباحث، بحث «هزینه یادگیری و آموزش» را هم اضافه کنید. شاید یکی بیاد بگه CPP فلان، اون یکی بهمان! ولی این سؤالات هم برای من نوعی که تیم گوگل کروم نوشته شده با CPP رو مدیریت نمیکنم (و به قول اونطرف آبیها یک Average Joe هستم!) مهم هستند:
- چندتا کتاب فارسی آموزشی خوب در این زمینه در کشور موجود است. من یادم میاد اولین کتاب VC منتشر شده در کشور پس از 450 صفحه به شما یاد میداد چطور با MFC دکمه به صفحه اضافه کنید، چطور منو درست کنید و همین! این شد برنامه نویسی CPP!
- چند عدد انجمن رفع اشکال فعال را که تاریخ آخرین به روز رسانی و پرسش و پاسخ آنها مثلا دیروز بوده را در مورد زبان xyz میتوان یافت؟
- اگر به مشکل برخوردم، کسی هست به داد من برسه؟ چه زمانی؟! مثلا هفته بعد یا تا آخر امروز؟
- چندتا وبلاگ فعال در این زمینه موجود است؟ آیا هستند کسانی که در این زمینهها فعالانه مطلب منتشر کنند؟ اطلاع رسانی کنند؟
- اگر کارمند برنامه نویس شرکتی امروز قهر کرد، مدیر بخش توسعه تا چه زمانی میتونه یک نفر رو جایگزین اون کنه؟ مثلا تا آخر ماه یا تا آخر سال؟! اون هم با چه کیفیتی؟ با چه دستمزدی؟
و اینجا است که وضعیت دات نت در ایران بسیار مطلوبتر از موارد مشابه به نظر میرسد. از نظر تعداد کتاب فارسی مهیا، تعداد انجمن، تعداد وبلاگ فعال و غیره.
اجرا نشدن پروژه
راه حل اول رفتن به تنظیمات nuget و تبدیل پروتکل ارتباطی به پروتکل http است که فقط کافیست حرف s را از https حذف کنید و آن مخزن را فعال کرده و در ابتدا قرار دهید.
راه حل دوم جلوگیری از این اتفاق و مداخله، با روشهای متداول ضد ف ی ل ت ر ی ن گ هست.
نکته دیگری هم وجود دارد که علیرغم وجود بستهای در پروژه، ممکن است علامت اخطاری وجود داشته باشد یا برنامه آن بسته را شناسایی نکرده باشد. در این حالت آن بسته را حذف کرده و مجدداً پروژه را build کنید.
پ.ن1: یک پروژه اگر نتواند بستههایش را دریافت کند، درست build نمیشود و بنابراین هر پروژه دیگری هم که از آن استفاده کرده باشد در build خود دچار خطار خواهد شد که به محض برطرف شدن اشکال اول، این پروژه نیز با موفقیت build خواهد شد.
پ.ن2: برخی از خطاهای اینجا بخاطر نبود برخی فایلها در پروژه دانلود شده است که اگر مجدداً دانلود کنید، اشکال برطرف شده است.
پ.ن3: گاهی نیز پیش میآید که باید بصورت دستی وارد عمل شده و برخی از پکیجها را با وارد کردن دستور دریافت آن بسته یا دستور دریافت مجدد آن بسته یا دستور آپدیت آن بسته، دریافت کرد.