مطالب
منسوخ شده‌ها در دات نت 4

برای کاهش حجم دات نت در نگارش‌های بعدی، کلاس‌هایی که توسط تیم‌های مختلف پیشتر توسعه یافته بودند، اکنون با هم تلفیق شده و نظم بهتری پیدا کرده‌اند. برای مثال کلیه کلاس‌های مرتبط با زبان‌های اسکریپتی اکنون به فضای نام System.CodeDom.Compiler.ICodeCompiler منتقل شده‌اند و غیره. مرجع نسبتا مفصلی در مورد منسوخ شده‌ها در دات نت 4 اخیرا منتشر شده است:

و حتما می‌دانید که چگونه یک متد یا نوع را باید به صورت منسوخ شده معرفی کرد:

در این حالت هنگام کامپایل برنامه، پیغام اخطاری توسط کامپایلر صادر خواهد شد.

مطالب
بلاگ‌ها و مطالب مطالعه شده در هفته قبل (هفته اول آبان)


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


Visual Studio

  • ویژوال استودیو 2010 و دات نت فریم ورک 4، نگارش CTP برای دریافت!

امنیت اطلاعات

ASP. Net

طراحی وب


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


به روز رسانی‌ها


ابزارها

سی‌شارپ
  • ویژگی‌های جدید C# 4.0 ، قسمت دوم، پارامترهای پیش فرض (یا آرگومانهای اختیاری). (چیزی شبیه به VB !! بدون نیاز به overloading برای پیاده سازی آن)

دلفی
  • ویدیویی از Delphi Prism . (نگارشی از دلفی که به شکل افزونه‌ای کاملا یکپارچه در VS.Net قابل دسترسی است)

SharePoint

ویندوز

متفرقه


مطالب
تولید خودکار کدهای سمت کلاینت بر اساس OpenAPI Specification
در سری «مستند سازی ASP.NET Core 2x API توسط OpenAPI Swagger» با نحوه‌ی تولید OpenAPI Specification، بر اساس کنترلرها و اکشن متدهای Web API خود آشنا شدیم و سپس با استفاده از ابزار Swagger-UI، یک رابط کاربری پویا را نیز برای آن تولید و سفارشی سازی کردیم. کاربرد OpenAPI Specification صرفا به مستندسازی یک Web API خلاصه نمی‌شود. بر اساس این استاندارد، ابزارهای متعددی جهت تولید کدهای سمت سرور و سمت کلاینت نیز طراحی شده‌اند که در اینجا نمونه‌ای از آن‌ها را بررسی خواهیم کرد.


تولید خودکار کدها بر اساس OpenAPI Specification

فرض کنید در حال توسعه‌ی برنامه‌ی سمت کلاینت Angular و یا سمت سرور ASP.NET Core ای هستید که هر دوی این‌ها از یک Web API استفاده می‌کنند. همچنین فرض کنید که این Web API را نیز خودتان توسعه می‌دهید. بنابراین حداقل کدی که باید در اینجا به اشتراک گذاشته شود، کدهای کلاس‌های DTO یا Data transfer objects هستند تا این کلاینت‌ها بتوانند اطلاعات Web API را به نحو صحیحی Deserialize کنند و یا برعکس، بتوانند اطلاعات را با فرمت صحیحی به سمت Web API ارسال کنند.
برای مدیریت این مساله می‌توان از دو روش استفاده کرد:
الف) استفاده از یک پروژه‌ی اشتراکی
اگر کدهای مدنظر، سمت سرور باشند، می‌توان یک پروژه‌ی اشتراکی را برای این منظور ایجاد کرد و کدهای DTO را درون آن قرار داد و سپس ارجاعی به آن را در پروژه‌های مختلف، استفاده نمود. به این ترتیب تکرار کدها، کاهش یافته و همچنین تغییرات آن نیز به تمام پروژه‌های استفاده کننده به نحو یکسانی اعمال می‌شوند. در این حالت یک اسمبلی اشتراکی تولید شده و به صورت مستقلی توزیع می‌شود.

ب) استفاده از روش لینک کردن فایل‌ها
در این روش پروژه‌های استفاده کننده از کلاس‌های DTO، فایل‌های آن‌را به پروژه‌ی خود لینک می‌کنند. در این حالت باز هم شاهد کاهش تکرار کدها و همچنین اعمال یک دست تغییرات خواهیم بود. اما در این روش دیگر یک اسمبلی اشتراکی وجود نداشته و کلاس‌های DTO هم اکنون با اسمبلی پروژه‌های استفاده کننده، یکی و کامپایل شده‌اند.

بدیهی است در هر دو روش، نیاز است بر روی کلاینت و API، کنترل کاملی وجود داشته باشد و بتوان به کدهای آن‌ها دسترسی داشت. به علاوه فایل‌های اشتراکی نیز باید بر اساس Target platform یکسانی تولید شده باشند. در این حالت دیگر نیازی به OpenAPI Specification برای تولید کدهای کلاینت دات نتی خود، نیست.

اما اگر کدهای API مدنظر در دسترس نباشند و یا بر اساس پلتفرم دیگری مانند node.js تولید شده باشد، کار یکپارچه سازی با آن دیگر با به اشتراک گذاری فایل‌های آن میسر نیست. در این حالت اگر این API به همراه یک OpenAPI Specification باشد، می‌توان از آن برای تولید خودکار کدهای کلاینت‌های آن استفاده کرد.


معرفی تعدادی از ابزارهایی که قادرند بر اساس OpenAPI Specification، کد تولید کنند

برای تولید کد از روی OpenAPI Specification، گزینه‌های متعددی در دسترس هستند:

الف) Swagger CodeGen
این ابزار را که جزئی از مجموعه ابزارهای تولید شده‌ی برفراز OpenAPI است، می‌توانید از آدرس swagger-codegen دریافت کنید. البته برای اجرای آن نیاز به Java Runtime است و یا نگارش آنلاین آن نیز در دسترس است: swagger.io
در ابزار آنلاین آن، در منوی generate بالای صفحه، گزینه‌ی تولید کد برای #C نیز موجود است.

ب)  AutoRest
محل دریافت: https://github.com/Azure/autorest
بر اساس node.js کار می‌کند و از طریق خط فرمان، قابل دسترسی است. همچنین این مورد ابزار تامین کننده‌ی گزینه‌ی Add REST client در ویژوال استودیو نیز می‌باشد. اما در کل، امکان تنظیمات آنچنانی را به همراه ندارد.

ج) NSwagStudio
محل دریافت: https://github.com/RSuter/NSwag/wiki/NSwagStudio
همانطور که در مطلب «مستند سازی ASP.NET Core 2x API توسط OpenAPI Swagger - قسمت اول - معرفی» نیز عنوان شد، NSwag یکی دیگر از تولید کننده‌های OpenAPI Specification مخصوص پروژه‌های دات نت است. NSwagStudio نیز جزئی از این مجموعه است که به کمک آن می‌توان کدهای کلاینت‌ها و DTOها را بر اساس OpenAPI Spec تولید کرد. همچنین امکان تنظیمات قابل توجهی را در مورد نحوه‌ی تولید کدهای نهایی به همراه دارد.


استفاده از NSwagStudio برای تولید کدهای DTOها

در اینجا از همان برنامه‌ای که در سری «مستند سازی ASP.NET Core 2x API توسط OpenAPI Swagger» بررسی کردیم، استفاده خواهیم کرد. بنابراین این برنامه، از پیش تنظیم شده‌است و هم اکنون به همراه یک تولید کننده‌ی OpenAPI Specification نیز می‌باشد. آن‌را اجرا کنید تا بتوان به OpenAPI Specification تولیدی آن در آدرس زیر دسترسی یافت:
 https://localhost:5001/swagger/LibraryOpenAPISpecification/swagger.json
سپس فایل msi مخصوص NSwagStudio را نیز از لینک آن در Github دریافت، نصب و اجرا کنید.


مطابق تصویر، ابتدا آدرس Swagger Specification URL یا همان آدرس فوق را وارد کنید. سپس فضای نام دلخواهی را وارد کرده و گزینه‌ی تولید کلاس‌های کلاینت را فعلا انتخاب نکنید. در لیست تنظیمات آن، گزینه‌ی Class Style نیز مهم است. برای مثال برای پروژه‌های ASP.NET Core حالت POCO را انتخاب کنید (plain old clr objects) و برای پروژه‌های مبتنی بر XAML، گزینه‌ی Inpc مناسب‌تر است چون RaisePropertyChanged‌ها را هم تولید می‌کند. در آخر بر روی دکمه‌ی Generate Outputs کلیک کنید تا خروجی ذیل حاصل شود:


یا می‌توان این خروجی را copy/paste کرد و یا می‌توان در برگه‌ی Settings، در انتهای لیست آن، مقدار output file path را مشخص کرد و سپس بر روی دکمه‌ی Generate files کلیک نمود تا فایل معادل آن تولید شود.


استفاده از NSwagStudio برای تولید کدهای کلاینت Angular استفاده کننده‌ی از API

NSwagStudio امکان تولید یک TypeScript Client را نیز دارد:

در اینجا ابتدا TypeScript Client را انتخاب می‌کنیم و سپس در تنظیمات آن، قالب Angular را انتخاب کرده و نگارش RxJS آن‌را نیز، 6 انتخاب می‌کنیم. در آخر بر روی Generate outputs کلیک می‌کنیم:


نکته‌ی جالب این خروجی، دقت داشتن به status codes درج شده‌ی در OpenAPI Spec است که در قسمت‌های چهارم و پنجم سری «مستند سازی ASP.NET Core 2x API توسط OpenAPI Swagger» آن‌ها را بررسی کردیم.
در اینجا نه تنها سرویسی جهت تعامل با API ما تولید شده‌است، بلکه معادل تایپ‌اسکریپتی DTOهای برنامه را نیز تولید کرده‌است:

مطالب
C# 8.0 - Nullable Reference Types
نوع‌های ارجاعی (Reference Types) در #C، همیشه نال‌پذیر بوده‌اند؛ در مقابل نوع‌های مقداری (value types) مانند DateTime که برای نال‌پذیر کردن آن‌ها باید یک علامت سؤال را در حین تعریف نوع آن‌ها ذکر کرد تا تبدیل به یک نوع نال‌پذیر شود (DateTime? Created). بنابراین عنوانی مانند «نوع‌های ارجاعی نال‌نپذیر» شاید آنچنان مفهوم نباشد.
خالق Null در زبان‌های برنامه نویسی، آن‌را یک اشتباه چند میلیارد دلاری می‌داند! و به عنوان یک توسعه دهنده‌ی دات نت، غیرممکن است که در حین اجرای برنامه‌های خود تابحال به null reference exception برخورد نکرده باشید. هدف از ارائه‌ی قابلیت جدید «نوع‌های ارجاعی نال‌نپذیر» در C# 8.0، مقابله‌ی با یک چنین مشکلاتی است و خصوصا غنی سازی IDEها برای ارائه‌ی اخطارهایی پیش از کامپایل برنامه، در مورد قسمت‌هایی از کد که ممکن است سبب بروز null reference exception شوند.


فعالسازی «نوع‌های ارجاعی نال‌نپذیر»

قابلیت «نوع‌های ارجاعی نال‌نپذیر» به صورت پیش‌فرض غیرفعال است. برای فعالسازی آن می‌توان فایل csproj را به صورت زیر، با افزودن خاصیت NullableContextOptions، ویرایش کرد:
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.0</TargetFramework>
    <LangVersion>8.0</LangVersion>
    <NullableContextOptions>enable</NullableContextOptions>
  </PropertyGroup>
</Project>
یک نکته: در نگارش‌های بعدی NET Core SDK. و همچنین ویژوال استودیو (از نگارش 16.2.0 به بعد)، خاصیت NullableContextOptions به صرفا Nullable تغییر نام یافته و ساده شده‌است. بنابراین اگر در این نگارش‌ها به خطاهای ذیل برخوردید:
CS8632: The annotation for nullable reference types should only be used in code within a ‘#nullable’ context.
CS8627: A nullable type parameter must be known to be a value-type or non-nullable reference type. Consider adding a ‘class’, ‘struct’ or type constraint.
صرفا به معنای استفاده‌ی از نام قدیمی این ویژگی است که باید به Nullable تغییر پیدا کند:
<PropertyGroup>
  <LangVersion>preview</LangVersion>
  <Nullable>enable</Nullable>
</PropertyGroup>
اما در زمان نگارش این مطلب که 3.0.100-preview5-011568 در دسترس است، فعلا همان نام قدیمی NullableContextOptions کار می‌کند.


تغییر ماهیت نوع‌های ارجاعی #C با فعالسازی NullableContextOptions


در #C ای که ما می‌شناسیم، رشته‌ها قابلیت پذیرش نال را دارند و همچنین ذکر آن‌ها به صورت nullable بی‌معنا است. اما پس از فعالسازی ویژگی نوع‌های ارجاعی نال‌نپذیر، اکنون عکس آن رخ می‌دهد. رشته‌ها نال‌نپذیر می‌شوند؛ اما می‌توان در صورت نیاز، آن‌ها را nullable نیز تعریف کرد.


یک مثال: بررسی تاثیر فعالسازی NullableContextOptions بر روی یک پروژه

کلاس زیر را در نظر بگیرید:
    public class Person
    {
        public string FirstName { get; set; }

        public string MiddleName { get; set; }

        public string LastName { get; set; }

        public Person(string first, string last) =>
            (FirstName, LastName) = (first, last);

        public Person(string first, string middle, string last) =>
            (FirstName, MiddleName, LastName) = (first, middle, last);

        public override string ToString() => $"{FirstName} {MiddleName} {LastName}";
    }
با فعالسازی خاصیت NullableContextOptions، بلافاصله اخطار زیر در IDE ظاهر می‌شود (اگر ظاهر نشد، یکبار پروژه را بسته و مجددا بارگذاری کنید):


در این کلاس، دو سازنده وجود دارند که یکی MiddleName را دریافت می‌کند و دیگری خیر. در اینجا کامپایلر تشخیص داده‌است که چون در سازنده‌ی اولی که MiddleName را دریافت نمی‌کند، مقدار پیش‌فرض خاصیت MiddleName، نال خواهد بود و همچنین ما NullableContextOptions را نیز فعال کرده‌ایم، بنابراین این خاصیت دیگر به صورت معمول و متداول یک نوع ارجاعی نال‌پذیر عمل نمی‌کند و دیگر نمی‌توان نال را به عنوان مقدار پیش‌فرض آن، به آن نسبت داد. به همین جهت اخطار فوق ظاهر شده‌است.
برای رفع این مشکل:
به کامپایلر اعلام می‌کنیم: «می‌دانیم که MiddleName می‌تواند نال هم باشد» و آن‌را در این زمینه راهنمایی می‌کنیم:
public string? MiddleName { get; set; }
پس از این تغییر، اخطار فوق که ذیل سازنده‌ی اول کلاس Person ظاهر شده بود، محو می‌شود. اما اکنون مجددا کامپایلر، در جائیکه می‌خواهیم از آن استفاده کنیم:
    public static class NullableReferenceTypes
    {
        //#nullable enable // Toggle to enable

        public static string Exemplify()
        {
            var vahid = new Person("Vahid", "N");
            var length = GetLengthOfMiddleName(vahid);

            return $"{vahid.FirstName}'s middle name has {length} characters in it.";

            static int GetLengthOfMiddleName(Person person)
            {
                string middleName = person.MiddleName;
                return middleName.Length;
            }
        }
    }
اخطارهایی را صادر می‌کند:


در اینجا در متد محلی (local function) تعریف شده، سعی در دسترسی به خاصیت MiddleName وجود دارد و اکنون با تغییر جدیدی که اعمال کردیم، به صورت نال‌پذیر تعریف شده‌است.
همچنین در سطر بعدی آن نیز نتیجه‌ی نهایی middleName، مورد استفاده قرار گرفته‌است که آن نیز مشکل‌دار تشخیص داده شده‌است.
مشکل اولین سطر را به این صورت می‌توانیم برطرف کنیم:
var middleName = person.MiddleName;
در اینجا بجای ذکر صریح نوع string، از var استفاده شده‌است. پیشتر با ذکر صریح نوع string، آن‌را یک رشته‌ی نال‌نپذیر تعریف کرده بودیم. اما اکنون چون person.MiddleName نال‌پذیر تعریف شده‌است، var نیز به صورت خودکار به این رشته‌ی نال‌پذیر اشاره می‌کند.
اما مشکل سطر دوم هنوز باقی است:


علت اینجا است که متغیر middleName نیز اکنون ممکن است مقدار نال را داشته باشد. برای رفع این مشکل می‌توان از اپراتور .? استفاده کرد و سپس اگر مقدار نهایی این عبارت نال بود، مقدار صفر را بازگشت می‌دهیم:
static int GetLengthOfMiddleName(Person person)
{
   var middleName = person.MiddleName;
   return middleName?.Length ?? 0;
}
هدف از این قابلیت و ویژگی کامپایلر، کمک کردن به توسعه دهنده‌ها جهت نوشتن کدهایی امن‌تر و مقاوم‌تر به null reference exception‌ها است.


امکان خاموش و روشن کردن ویژگی نوع‌های ارجاعی نال‌نپذیر به صورت موضعی

زمانیکه خاصیت NullableContextOptions را فعال می‌کنیم، بر روی کل پروژه تاثیر می‌گذارد. برای مثال اگر یک چنین قابلیتی را بر روی پروژه‌های قدیمی خود فعال کنید، با صدها اخطار مواجه خواهید شد. به همین جهت است که این ویژگی حتی با فعالسازی C# 8.0 و انتخاب آن، به صورت پیش‌فرض غیرفعال است. بنابراین برای اینکه بتوان پروژه‌های قدیمی را قدم به قدم و سر فرصت، «مقاوم‌تر» کرد، می‌توان تعیین کرد که کدام قسمت، تحت تاثیر این ویژگی قرار بگیرد و کدام قسمت‌ها خیر:
public static class NullableReferenceTypes
{
#nullable disable // Toggle to enable
در اینجا می‌توان با استفاده از compiler directive جدید nullable# به کامپایلر اعلام کرد که از این قسمت صرفنظر کن. مقدار آن می‌تواند disable و یا enable باشد.


مجبور ساختن خود به «مقاوم سازی» برنامه

اگر NullableContextOptions را فعال کنید، کامپایلر صرفا یکسری اخطار را در مورد مشکلات احتمالی صادر می‌کند؛ اما برنامه هنوز کامپایل می‌شود. برای اینکه خود را مقید به «مقاوم سازی» برنامه کنیم، می‌توانیم با فعالسازی ویژگی TreatWarningsAsErrors در فایل csprj، این اخطارها را تبدیل به خطای کامپایلر کرده و از کامپایل برنامه جلوگیری کنیم:
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.0</TargetFramework>
    <LangVersion>8.0</LangVersion>
    <NullableContextOptions>enable</NullableContextOptions>
    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
  </PropertyGroup>
</Project>
البته TreatWarningsAsErrors تمام اخطارهای برنامه را تبدیل به خطا می‌کند. اگر می‌خواهید انتخابی‌تر عمل کنید، می‌توان از خاصیت WarningsAsErrors استفاده کرد:
<WarningsAsErrors>CS8600;CS8602;CS8603</WarningsAsErrors>


آیا اگر برنامه‌ای با C# 7.0 کامپایل شود، کتابخانه‌های تهیه شده‌ی با C# 8.0 را می‌تواند استفاده کند؟

پاسخ: بله. از دیدگاه برنامه‌های قدیمی، کتابخانه‌های تهیه شده‌ی با C# 8.0، تفاوتی با سایر کتابخانه ندارند. آن‌ها نوع‌های نال‌پذیر جدید را مانند ?string مشاهده نمی‌کنند؛ آن‌ها فقط string را مشاهده می‌کنند و روش کار کردن با آن‌ها نیز همانند قبل است. بدیهی است در این حالت از مزایای کامپایلر C# 8.0 در تشخیص زود هنگام مشکلات برنامه محروم خواهند بود؛ اما عملکرد برنامه تفاوتی نمی‌کند.


وضعیت برنامه‌ی C# 8.0 ای که از کتابخانه‌های C# 7.0 و یا قبل از آن استفاده می‌کند، چگونه خواهد بود؟

چون کتابخانه‌های قدیمی‌تر از مزایای کامپایلر C# 8.0 استفاده نمی‌کنند، خروجی‌های آن بدون بروز خطایی توسط کامپایلر C# 8.0 استفاده می‌شوند؛ چون حجم اخطارهای صادر شده‌ی در این حالت بیش از حد خواهد بود. یعنی این بررسی‌های کامپایلر صرفا برای کتابخانه‌های جدید فعال هستند و نه برای کتابخانه‌های قدیمی.


مهارت‌های مواجه شدن با اخطارهای ناشی از فعالسازی NullableContextOptions

در مثالی که بررسی شد، یک نمونه از روش‌های مواجه شدن با اخطارهای ناشی از فعالسازی ویژگی نوع‌های ارجاعی نال‌نپذیر را بررسی کردیم. در ادامه روش‌های تکمیلی دیگری را بررسی می‌کنیم.

1- هرجائیکه قرار است متغیر ارجاعی نال‌پذیر باشد، آن‌را صراحتا اعلام کنید.
string name = null; // ERROR
string? name = null; // OK!
این مثال را پیشتر بررسی کردیم. با فعالسازی ویژگی نوع‌های ارجاعی نال‌نپذیر، ماهیت آن‌ها نیز تغییر می‌کند و دیگر نمی‌توان به آن‌ها null را انتساب داد. اگر نیاز است حتما اینکار صورت گیرد، آن‌ها را توسط ? به صورت nullable تعریف کنید.
نمونه‌ی دیگر آن مثال زیر است:
public class Person
{
    public Address? Address { get; set; };
    public string Country => Address?.Country;   // ERROR! 
}
در اینجا Address یک نوع ارجاعی نال‌پذیر است. بنابراین حاصل Address?.Country می‌تواند نال باشد و به Country نال‌نپذیر قابل انتساب نیست. برای رفع این مشکل کافی است دقیقا مشخص کنیم که این رشته نیز نال‌پذیر است:
public class Person
{
    public Address? Address { get; set; };
    public string? Country => Address?.Country;  // OK!
}

البته در این حالت باید به مثال زیر دقت داشت:
var node = this; // Initialize non-nullable variable
while (node != null)
{
   node = null; // ERROR!
}
چون node در اینجا توسط var تعریف شده‌است، دقیقا نوع this را که non-nullable است، پیدا می‌کند. بنابراین بعدها نمی‌توان به آن null را انتساب داد. اگر چنین موردی نیاز بود، باید صریحا نوع آن‌را بدو امر، nullable تعریف کرد؛ چون هنوز امکان تعریف ?var میسر نیست:
Node? node = this;   // Initialize nullable variable
while (node != null) {
   node = null; // OK!
}


2- نوع‌های خود را مقدار دهی اولیه کنید.
در مثال زیر:
public class Person
{
   public string Name { get; set; } // ERROR!
}
در این حالت چون خاصیت Name، در سازنده‌ی کلاس مقدار دهی اولیه نشده‌است، یک اخطار صادر می‌شود که بیانگر احتمال نال بودن آن است. یک روش مواجه شدن با این مشکل، تعریف آن به صورت یک خاصیت نال‌پذیر است:
public class Person
{
   public string? Name { get; set; }
}

یا یک استثناء را صادر کنید:
public class Person
{
    public string Name { get; set; }
    public Person(string name) {
        Name = name ?? throw new ArgumentNullException(nameof(name));
    }
}
به این ترتیب کامپایلر می‌داند که اگر نام دریافتی نال بود، دقیقا باید چگونه رفتار کند.
البته در این حالت برای مقدار دهی اولیه‌ی Name، حتما نیاز به تعریف یک سازنده‌است و در این حالت کدهایی را که از سازنده‌ی پیش‌فرض استفاده کرده بودند (مانند new Person { Name = "Vahid" })، باید تغییر دهید.

راه‌حل دیگر، مقدار دهی اولیه‌ی این خواص بدون تعریف یک سازنده‌ی اضافی است:
public class Person
{
   public string Name { get; set; } = string.Empty;
   // -or-
   public string Name { get; set; } = "";
}
برای مثال می‌توان از مقادیر خالی زیر برای مقدار دهی اولیه‌ی رشته‌ها، آرایه‌ها و مجموعه‌ها استفاده کرد:
String.Empty
Array.Empty<T>()
Enumerable.Empty<T>()
یا حتی می‌توان اشیاء دیگر را نیز به صورت زیر مقدار دهی اولیه کرد:
public class Person
{
   public Address Address { get; set; } = new Address();
}
البته در این حالت باید مفهوم فلسفی «خالی بودن» را پیش خودتان تفسیر و تعریف کنید که دقیقا مقصود از یک آدرس خالی چیست؟ به همین جهت شاید تعریف این شیء به صورت nullable بهتر باشد.
مطالب
OpenCVSharp #1
معرفی OpenCV

پردازش تصاویر علمی است برای پیاده سازی الگوریتم‌های مختلفی بر روی تصاویر دیجیتال؛ برای مثال تشخیص خودکار شماره‌ی پلاک خودروهای وارد شده‌ی به محدوده‌ی طرح ترافیک، تا تشخیص چهره‌ی افراد، در گوشی‌های همراه. پردازش تصاویر، در صنایع مختلف، علوم پزشکی و همچنین نظامی، کاربردهای بسیاری دارند.
برای انجام این کار، کتابخانه‌های بسیار زیادی طراحی شده‌اند؛ اما در این بین OpenCV جایگاه خاصی دارد. این کتابخانه‌ی بسیار مشهور سورس باز، جهت پردازش تصاویر در سیستم عامل‌های مختلفی مانند Windows, Mac, Linux, Android و iOS بکار می‌رود.


محصور کننده‌های OpenCV مخصوص دات نت

تا امروز محصور کننده‌های زیادی جهت استفاده‌ی از کتابخانه‌ی OpenCV در دات نت طراحی شده‌اند که تعدادی از مهم‌ترین‌های آن‌ها به شرح زیر هستند:

الف) Emgu CV
این کتابخانه، یکی از مشهورترین محصور کننده‌های OpenCV است و دارای مجوزی دوگانه می‌باشد. برای کارهای سورس باز، مجوز GPL دارد (یعنی باید کارتان را سورس باز کنید) و برای کارهای تجاری باید مجوز آن‌را بخرید. البته باید توجه داشت که مجوز کتابخانه‌ی اصلی OpenCV از نوع BSD است و این محدودیت‌ها را ندارد.

ب) OpenCvSharp
کتابخانه‌ی OpenCvSharp دارای مجوز BSD است (همانند کتابخانه‌ی اصلی OpenCV) و محدودیتی برای استفاده ندارد. هر دو نوع مدل برنامه نویسی OpenCV را که شامل متدهای C و ++C آن‌است، پشتیبانی می‌کند و در طراحی آن سعی شده‌است که بیشترین نزدیکی به طراحی اصلی OpenCV وجود داشته باشد. همچنین این کتابخانه چندسکویی بوده و با Mono لینوکسی نیز سازگار است و از دات نت 2 به بعد را نیز پشتیبانی می‌کند. جامعه‌ی کاربری آن فعال است و مدام به روز می‌شود.

ج) SharperCV
دیگر نگهداری نمی‌شود.

د) OpenCVDotNet 
آخرین تاریخ به روز رسانی آن سال 2007 است.

ه) DirectCV
آخرین تاریخ به روز رسانی آن سال 2011 است.


در این بین یکی از بهترین انتخاب‌ها، کتابخانه‌ی OpenCvSharp ژاپنی است. مجوز استفاده‌ی از آن محدود نیست. به روز رسانی مرتب و منظمی دارد و API آن طوری طراحی شده‌است که به سادگی بتوانید مثال‌های C و ++C کتابخانه‌ی OpenCV را تبدیل به معادل‌های #C کنید.


نصب OpenCvSharp

برای نصب کتابخانه‌ی OpenCvSharp می‌توان از بسته‌های نیوگت آن کمک گرفت. این کتابخانه به همراه دو بسته‌ی نیوگت ارائه می‌شود.
اگر فرمان ذیل را صادر کنید
 PM> Install-Package OpenCvSharp-AnyCPU
علاوه بر اسمبلی‌های دات نتی OpenCVSharp، کتابخانه‌ی native مربوط به OpenCV سازگار با نگارش ارائه شده را نیز دریافت خواهید کرد.
و اگر دستور ذیل را اجرا کنید:
 PM> Install-Package OpenCvSharp-WithoutDll
به این معنا است که تنها اسمبلی‌های دات نتی OpenCVSharp را دریافت می‌کنید. در این حالت نیاز است به سایت OpenCV مراجعه و بسته‌های کامپایل شده‌ی آن‌را دریافت کنید. سپس فایل‌های dll موجود در پوشه‌ی opencv\build\x64\vc12\bin را برای مثال به پوشه‌ی bin پروژه‌ی خود کپی نمائید.

روش توصیه شده‌ی در اینجا، همان نصب بسته‌ی نیوگت OpenCvSharp-AnyCPU است. به این ترتیب نگارش‌های X86 و X64 کتابخانه‌ی OpenCV سازگار با OpenCvSharp را نیز دریافت خواهید کرد.


نکته‌ای در مورد ارائه‌ی نهایی پروژه‌های مبتنی بر OpenCV

OpenCV یک کتابخانه‌ی native ویندوز است و دات نتی نیست . بنابراین DLL‌های آن باید بسته به معماری CPU جاری، انتخاب شوند. یعنی اگر برنامه‌ی دات نتی خود را در حالت Any CPU کامپایل می‌کنید، این برنامه در یک سیستم 64 بیتی، 64 بیتی رفتار می‌کند و در یک سیستم 32 بیتی، 32 بیتی. بنابراین باید دقت داشت که اگر سیستم جاری 64 بیتی است و می‌خواهید از اسمبلی‌های X86 مربوط به OpenCV استفاده کنید، برنامه با پیام استثنای یافت نشدن OpenCV و BadImageFormatException کرش خواهد کرد. بسته‌ی نیوگت OpenCvSharp-AnyCPU  شامل هر دو معماری X86 و X64 است و هر دو سری DLLهای OpenCV را به همراه دارد.
همچنین OpenCV تحت ویندوز، توسط کامپایلر ویژوال ++C، کامپایل شده‌است. به همین جهت در این حالت، علاوه بر نصب دات نت، نیاز است VC++ redistributable packages را نیز بر روی کامپیوتر کلاینت نصب کرد.
پس از نصب بسته‌ی نیوگت OpenCvSharp-AnyCPU اگر به پوشه‌ی bin برنامه‌ی خود مراجعه کنید، پوشه‌ی جدید dll را نیز می‌توان مشاهده کرد. داخل این پوشه، دو پوشه‌ی X86 و X64 وجود دارند که حاوی DLLهای اصلی OpenCV می‌باشند. در این پوشه‌ها اگر برای مثال فایلی به نام msvcp120.dll را یافتید، یعنی این نگارش از OpenCV نیاز به بسته‌های مخصوص VC++ 12 دارد.

رعایت این دو نکته بسیار مهم است؛ در غیر اینصورت برنامه‌ی شما آغاز نخواهد شد.


اولین برنامه‌ی OpenCVSharp


پس از نصب بسته‌ی نیوگت OpenCvSharp-AnyCPU، مقدمات نصب OpenCV به پایان می‌رسد. در ادامه یک برنامه‌ی کنسول جدید را ایجاد کرده و کدهای ذیل را به آن اضافه کنید:
using OpenCvSharp;
 
namespace OpenCVSharpSample01
{
    class Program
    {
        static void Main(string[] args)
        {
            var img = Cv.CreateImage(new CvSize(128, 128), BitDepth.U8, 1);
 
            for (var y = 0; y < img.Height; y++)
            {
                for (var x = 0; x < img.Width; x++)
                {
                    Cv.Set2D(img, y, x, x + y);
                }
            }
 
            Cv.NamedWindow("window");
            Cv.ShowImage("window", img);
            Cv.WaitKey();
            Cv.DestroyWindow("window");
 
            Cv.ReleaseImage(img);
        }
    }
}
این خروجی را دریافت خواهید کرد:


در این مثال یک تصویر 128*128 ایجاد شده و سپس با گرادیانی از رنگ خاکستری پر می‌شود. در ادامه یک پنجره‌ی native مخصوص OpenCV ایجاد شده و این تصویر در آن نمایش داده می‌شود.


کدهای کامل این مثال را از اینجا می‌توانید دریافت کنید.
مطالب
نحوه‌ی فعال سازی library caching زمانیکه یک Silverlight library را تولید کرده‌ایم

در مورد کاهش حجم فایل‌های XAP سیلورلایت زمانیکه از اسمبلی‌های کتابخانه‌های دیگر مانند Silverlight toolkit استفاده می‌شود، در این فصل بحث شده است و راه حل، استفاده از گزینه‌ی reduce XAP size by using application library caching است. به این صورت کاربران دیگر به ازای هر بار مشاهده‌ی سایت نیازی نخواهند داشت تا یک سری کتابخانه‌ی کمکی را که هیچ تغییری در آن‌ها حاصل نخواهد شد، دریافت کنند و اطلاعات آن‌ها از cache مرورگر خوانده می‌شود. این مورد با کتابخانه‌ها و ابزارهای کمکی تولید شده توسط مایکروسافت کار می‌کند. اما اگر خودتان یک Silverlight library را تولید کنید، چنین اتفاقی رخ نخواهد داد و باز هم فایل اسمبلی کتابخانه‌ی شما درون فایل XAP اصلی برنامه قرار گرفته و خبری از caching مجزای آن نیست. چرا اینطور است؟ چکار باید کرد؟!
علت آن بر می‌گردد به نحوه‌ی پیاده سازی library caching در VS.NET و Silverlight . برای این منظور چند مرحله باید طی شود تا این قابلیت برای کتابخانه‌های ساخت خودمان نیز فعال گردد:
الف) به کتابخانه‌ی خود باید امضای دیجیتال اضافه کنید:
اینکار با استفاده از امکانات خود VS.NET بسیار ساده است. به خواص پروژه مراجعه کنید. سپس برگه‌ی Signing را باز کرده و گزینه‌ی Sign the assembly را انتخاب کنید (شکل زیر). در قسمت choose a strong name key file ، گزینه‌ی new را انتخاب کرده و پس از وارد کردن یک نام دلخواه و گذر واژه‌ای، فایل pfx امضای دیجیتال اسمبلی شما تولید خواهد شد. اکنون تنها کافی است یکبار دیگر برنامه را کامپایل کنید.


ب) به یک فایل extMap.xml هم نیاز است:
هنگام پیاده سازی قابلیت library caching ، VS.NET به دنبال فایلی به نام AssemblyFileName.extmap.xml دقیقا در کنار فایل اسمبلی مورد نظر می‌گردد. ساختار عمومی این فایل XML به صورت زیر است:

<?xml version="1.0"?>
<manifest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<assembly>
<name>SLHelper</name>
<version>1.0.0.0</version>
<publickeytoken>f265933def965412</publickeytoken>
<relpath>SLHelper.dll</relpath>
<extension downloadUri="SLHelper.zip" />
</assembly>
</manifest>

نام، شماره نگارش، مسیر قرارگیری فایل اسمبلی مورد نظر و همچنین نام نهایی آن حین جدا سازی آن از XAP برنامه باید مشخص گردد. گزینه‌ی publickeytoken مهم‌ترین تنظیم این فایل است و قسمت الف را به همین منظور نیاز داشتیم. این عدد را به سادگی با استفاده از برنامه‌ی reflector می‌توان بدست آورد (شکل زیر).



جهت ساده سازی قسمت (ب)، برنامه‌ی کمکی را از آدرس ذیل می‌توانید دریافت کنید:
Utility: Extmap Maker

برای مطالعه بیشتر
Silverlight 3: Cached Assemblies and you can to

نظرات مطالب
معرفی ELMAH
خلاصه مطلب ذکر شده این است: در حالت release، باید فایل pdb متناظر با dll پروژه شما در کنارش باشد تا شماره خط متناظر با استثنای رخ داده شده، قابل لاگ کردن باشد.

مطالب
آناتومی یک گزارش خطای خوب
به مشکلی در برنامه‌ای برخورده‌اید؟ کتابخانه‌ای کار نمی‌کند؟ خطایی را دریافت کرده‌اید؟ برنامه کامپایل نمی‌شود؟ برنامه آنطور که مدنظر شما است رفتار نمی‌کند؟ برای طرح این مسایل، صرف عنوان کردن «برنامه کار نمی‌کنه» یا «خطا می‌ده» منزلت خودتان را تا حد یک کاربر عادی تازه کار تنزل داده‌اید. در ادامه ساختار یک گزارش خطای خوب را بررسی خواهیم کرد، تا شما را سریعتر به مقصودتان برساند و همچنین کار پیگیری برنامه نویس یا برنامه نویس‌های مسئول را نیز مقداری ساده‌تر کند.


کارهای لازم پیش از طرح سؤال
- سعی کنید انجمن‌های مرتبط را یکبار بررسی و جستجو کنید.
- عین خطای دریافتی را در گوگل جستجو کنید. اگر از برنامه‌ها یا کتابخانه‌های معروف و متداول استفاده می‌کنید، یکی از مزیت‌های مهم کار با آن‌ها، «تنها نبودن» است! یقین داشته باشید خطایی را که دریافت کرده‌اید پیشتر توسط ده‌ها نفر دیگر در سایت‌های مختلف مطرح شده‌اند و بالاخره با بررسی آن‌ها می‌توان به پاسخ رسید.
- شاید راهنمای برنامه در این مورد خاص مطلبی را عنوان کرده است.

و ... به صورت خلاصه باید بتوانید به این سؤال پاسخ دهید: «خودت چکار کردی؟». حداقل نشان دهید که فرد حاضر و آماده طلبی نیستید و پیشتر یک حداقل تقلایی را انجام داده‌اید.


کجا باید سؤال پرسید؟
- اگر به انجمنی برای طرح سؤال خود مراجعه کرده‌اید، حتما زیر شاخه صحیحی را انتخاب کنید تا سؤال شما بسته نشود یا کلا حذف نگردد. برای مثال سؤال ASP.NET را در بخش سی‌شارپ نپرسید یا برعکس یا اگر سایتی مقاله‌ای را منتشر کرده، ذیل آن در مورد نحوه بک آپ گرفتن از اکانت توئیتر خود سؤال نپرسید!
- اگر پاسخی را دریافت کردید، ادامه بحث را ذیل همان مطلب پیگیری کنید و مجددا مطلب جدیدی را ایجاد نکنید.
- اگر تا نیم ساعت بعد جوابی را دریافت نکردید، کل بخش‌های یک سایت را با ارسال پیام خود اسپم نکنید. یکبار ارسال یک سؤال کافی است. اکثر این سایت‌ها حالت یک «چت آفلاین» را دارند. به این معنا که ابتدا پیغام خود را می‌گذارید، اگر مدتی بعد (ممکن است چند ساعت بعد) شخصی آن‌را مشاهده کرد و قادر به پاسخ دهی بود، به شما کمک خواهد کرد. بنابراین اگر سریعا به جواب نرسیدید، نه کل سایت را اسپم کنید و نه ... شروع به رفتارهای ناشایست کنید. اینکار با فریاد کشیدن وسط یک جمع تفاوتی ندارد. اشخاص مرتبط همواره آنلاین نیستند؛ ضمنا ممکن است واقعا پاسخی برای یک سؤال نداشته باشند. منصف باشید.
- از ایمیل‌های خصوصی افراد یا قسمت پیام‌های خصوصی سایت‌ها برای ارسال سؤالات شخصی استفاده نکنید. ایمیل خصوصی، مخصوص کارهای شخصی است. قسمت پیام‌های خصوصی یک سایت عموما مخصوص رسیدگی به مشکلات کاربری است. این تصور را نداشته باشید که اشخاص مشاور شخصی رایگان پروژه‌های تجاری شما هستند.
- بهترین محل برای پرسیدن سؤالات مرتبط با یک پروژه خاص، mailing list یا انجمن گفتگو و یا issue tracker آن پروژه است. وقت خودتان را با ارسال خطاهای یک پروژه خاص، در یک انجمن عمومی و همه منظوره تلف نکنید. کمی جستجو کنید که سایت اصلی پروژه کجا است. بعد دقت کنید آیا جایی برای پرسش و پاسخ دارد یا خیر. اکثر پروژه‌های خوب، مکانی را جهت جمع آوری بازخوردهای پروژه خود، اختصاص می‌دهند.


چطور باید سؤال پرسید؟
سؤال فنی خوب پرسیدن هم یک هنر است؛ که تعدادی از مشخصه‌های مهم آن‌را در ذیل مرور خواهیم کرد:
- عنوان مناسبی را برای سؤال خود انتخاب کنید. «لطفا کمک کنید» یا «من مشکل دارم» یا «مشکل در پروژه»، عموما واکنش‌های تندی را به همراه دارند؛ و تا حد ارسال اسپم در یک سایت بی‌کیفیت تلقی می‌شوند. ضمن اینکه انتخاب عنوان‌های مناسب، جستجوهای بعدی را در سایت ساده می‌کنند و کمک بزرگی خواهند بود به افراد بعدی.
- محیطی را که خطا در آن رخ داده است، توضیح دهید. ذکر IIS تنها کافی نیست. کدام نگارش آن؟ در کدام ویندوز؟
برای مثال شماره نگارش کتابخانه یا نرم افزار مورد استفاده را ذکر کنید. شاید خطایی که گرفته‌اید در نگارش بعدی آن برطرف شده است.
ذکر شماره نگارش VS.NET یا شماره نگارش دات نت مورد استفاده، سیستم عامل و کلا توصیف محیط بروز خطا، عموما بسیار مفید هستند.
- حتما کل خطای دریافت شده را ارسال کنید. اگر در یک برنامه C خطایی حاصل شود، احتمالا شکلی مانند Error 0xABCD را دارد. اما استثناءهای دات نت به همراه stack trace و حتی شماره سطر خطای حاصل نیز هستند. همین مساله می‌تواند به خطایابی نهایی بسیار کمک کند.
- سؤال خود را طوری مطرح کنید که شخص مقابل بتواند آن‌را در کمترین زمان ممکن «باز تولید» کند. برای مثال ذکر خطای دریافتی بسیار خوب است. اگر داده‌ای که سبب بروز این خطا شده است را هم ارسال کنید، مفید‌تر خواهد بود؛ یا اگر دستور پاور شل خاصی در کنسول نیوگت خطا می‌دهد، صرفا عنوان نکنید که جواب نگرفته‌اید. چه دستوری را اجرا کرده‌اید؟ چه خطایی را دریافت کرده‌اید؟ ساختار پروژه شما چیست؟ آیا شخص مقابل می‌تواند بر اساس اطلاعاتی که ارائه دادید یک آزمایش شخصی را تدارک ببیند؟ آیا می‌تواند آن‌را با توضیحات شما مجددا تولید کند؟
زمان باز تولید خطا را هم مدنظر داشته باشید. برای مثال اگر بتوانید قطعه کدی را ارائه دهید که در کمترین زمان ممکن، صرفا با کپی و پیست آن در VS.NET قابل کامپایل باشد، بسیاری علاقمند به پاسخگویی به شما خواهند شد. در غیراینصورت آنچنان انتظار نداشته باشید که شخص پاسخ دهنده وقت زیادی را برای رسیدگی به جزئیات سؤال شما صرف کند؛ یا مدتی مشغول به تهیه یک مثال جدید بر مبنای توضیحات شما شود.
حجم کدهای ارسالی شما نیز در اینجا مهم هستند. کل پروژه خود را ارسال نکنید! سعی کنید یک مثال کوچک را که بتواند سریعا خطای مدنظر شما را بازتولید کند، ارسال کنید و نه بیشتر. همچنین کدهایی که برای اجرا نیاز به GUI نداشته باشند نیز در این حالت اولویت دارند.
و به صورت خلاصه، خودتان را بجای پاسخ دهنده قرار دهید. آیا با چند جمله‌ای که ارائه داده‌اید، می‌توان انتظار پاسخی را داشت یا خیر.
- ایمیل شخصی خود را در انتهای پیام ارسال نکنید. کسی اهمیتی نمی‌دهد! اگر سؤال شما پاسخی داشته باشد، همانجا دریافت خواهید کرد و نه در میل باکس شخصی.
- املاء و انشای متنی را که ارسال می‌کنید، یکبار بررسی کنید. اگر برای شما اهمیتی ندارد که چه کلمات و جمله بندی را باید بکار برد، برای شخص مقابل هم آنچنان اهمیتی نخواهد داشت که زیاد وقت صرف کند.
- از بکار بردن smileyهای بیش از حد یا قرار دادن تعداد علامت تعجب‌های بیش از حد خودداری کنید. این موارد عموما به مسخره کردن شخص مقابل تفسیر می‌شوند.
- در بدو امر فریاد نکشید که «باگ» پیدا کرده‌اید؛ خصوصا اگر به mailing list اختصاصی یک پروژه پیامی را ارسال می‌کنید. چون اگر مشکل شما واقعا باگ نباشد، بیشتر یک توهین تلقی خواهد شد و در دفعات بعدی پاسخ دادن به شما به صورت ضمنی مؤثر خواهند بود؛ یا جواب نمی‌گیرید و یا جدی گرفته نخواهید شد.  
- هدف از کاری را که مشغول به انجام آن بود‌ه‌اید را نیز ذکر کنید. ذکر خطای دریافتی بسیار مفید است اما اگر بتوانید یک دید کلی را نسبت به کاری که مشغول به آن بوده‌اید، ایجاد کنید، شاید پاسخ بهتری را دریافت کنید. برای مثال جهت رسیدن به هدف و مقصود شما بهتر است از روش دیگری استفاده کنید.
- پس از اینکه پیامی را دریافت کردید، یک حداقل واکنشی را ارسال کنید. مثلا خوب بود؛ کمک کرد و یا مفید نبود. همین واکنش‌ها در آینده به کمک نتایج جستجوهای انجام شده خواهند آمد و اشخاص بعدی حداقل خواهند دانست که پاسخ داده شده صحیح بوده است یا خیر.

و همیشه بخاطر داشته باشید: تمام خدماتی که سایت‌های عمومی به شما ارائه می‌دهند «یک لطف» است و حقی را برای شما ایجاد نمی‌کنند. این اشخاص از شما پول نمی‌گیرند تا به سؤالات شما پاسخ دهند یا تبدیل به مشاور خصوصی رایگان شما شوند. می‌توانید محیط را برای این اشخاص، با اندکی احترام، ملایمت و انصاف، دلپذیرتر کنید.
مطالب
انتقال SVN به یک سیستم جدید

در راستای مهاجرت به ویندوز 7، کار نصب و راه اندازی SVN و کلاینت‌های آن باید مجددا انجام می‌شد. اگر برای بار اول است که به مبحث SVN برخورد می‌کنید، مطالعه این جزوه توصیه می‌شود. مطالب ذیل برای افرادی مفید است که قصد انتقال سیستم SVN موجود خود را به مکان و یا سیستم عامل دیگری در اسرع وقت دارند.

الف) دریافت و نصب Visual SVN server
یا می‌توان SVN خالص را از سایت آن دریافت کرد و یا جهت سهولت کار و همچنین دسترسی به یک کنسول مدیریتی می‌توان برنامه‌ی رایگان Visual SVN server را از آدرس زیر دریافت و نصب کرد:

پس از نصب، ابتدا باید یا کاربر جدیدی را جهت استفاده از منابع آن تعریف کرد و یا از نحوه‌ی اعتبار سنجی یکپارچه با ویندوز هم می‌توان استفاده کرد که من از این روش دوم استفاده می‌کنم (شکل زیر، کلیک راست بر روی نود اصلی visual SVN server و سپس انتخاب خواص و مراجعه به برگه‌ی اعتبار سنجی آن):



ب)دریافت و نصب TortoiseSVN

نصب آن نکته‌ی خاصی ندارد. اما یک سری نکته‌ی ریز پس از نصب آن بهتر است رعایت شود که در ادامه ذکر می‌شود:

ج) دریافت و نصب برنامه‌ی WinMerge
برنامه‌ی Diff پیش فرض TortoiseSVN آنچنان قوی نیست. به همین جهت می‌توان برنامه‌ی WinMerge را با آن یکپارچه کرد. برای این منظور ابتدا آن‌را دریافت نمائید:

اگر پس از نصب TortoiseSVN آن‌را نصب کنید، در حین نصب پیشنهاد یکپارچه سازی با TortoiseSVN را نیز می‌دهد. اگر ابتدا WinMerge را نصب کرده‌اید و سپس TortoiseSVN بر روی سیستم شما نصب شده، فقط کافی است مطابق شکل زیر ابتدا به قسمت Diff viewers آن مراجعه کرده و سپس با انتخاب گزینه‌ی external ، دستور خط فرمان زیر را وارد نمائید:

C:\Program Files (x86)\WinMerge\WinMergeU.exe -e -x -ub -dl %bname -dr %yname %base %mine



بدیهی است مسیر WinMergeU.exe مطابق مسیر نصب در سیستم شما باید تنظیم شود.

د) تنظیم مسیر تحت نظر قرار گرفتن سیستم
TortoiseSVN به صورت پیش فرض کل سیستم را جهت مشاهده‌ی تغییرات تحت نظر قرار می‌دهد که گاهی باعث کاهش کارآیی آن خواهد شد. برای رفع این مشکل می‌توان مسیرهایی را که پروژه‌های شما در آن قرار دارند را به آن معرفی نمود تا بار کلی سیستم کاهش یابد.



همانطور که در شکل نیز ملاحظه می‌کنید، Include path مقدار دهی شده است.

ه) مشخص سازی پسوندهایی که بهتر است از آن‌ها صرفنظر شود
به برگه‌ی general تنظیمات TortoiseSVN مراجعه کرده و در قسمت global ignore pattern آن، موارد زیر را وارد نمائید:



این موارد شامل پروژه‌های دات نت، دلفی ، VC و امثال آن است و همچنین یک سری فایل بایناری که عموما با پروژه‌های برنامه نویسی نیازی به ثبت نگارش آن‌ها نیست.

*.dcu *.~* dcu temp *.exe *.zip *.bkm *.ddp *.cfg *.dof *.dsk *.ini *.hlp *.gid *.bmp *.png *.gif ~* *.log bin debug release *.map *.chm *.bkf Thumbs.db *.mdb .obj *.elf *.stat *.ddp *.bpl *.map *.GID *.hlp *.opt *.dll *.raw *.BIN *.obj *.pdb *.scc Debug Release *.xml obj *.~* *.backup *.INI *.ArmLog *.KeyLog *.NanoLog *.Stats *.PreARM *.old *.drc *.*~ *.doc *.pdf *.bmp *.jpg *.MRW *.NEF *.ORF *.psd *.X3F __history *.local *.identcache *.bak Thumbs.db *.ldb *.dex *.rar DllDcu *.lck CVS cvs *.txt *.TXT *.jdbg *.HLP *.KWF *.xls *.cnt *.dsm *.dti *.tmp *.lnk *.cbk *.mes *.suo *.ncb *.user _ReSharper.* [Bb]in obj [Dd]ebug [Rr]elease *.aps *.eto


در همین برگه، اگر هنوز از VS2003 استفاده می‌کنید، تیک مربوط به استفاده از _svn بجای .svn را قرار دهید تا VS.Net با پوشه‌های مدیریتی ذکر شده مشکل پیدا نکند.

و) نصب افزونه‌های SVN سازگار با VS.Net
یا می‌توان از افزونه‌ی Visual SVN استفاده کرد (که رایگان نیست) و یا AnkhSVN که رایگان و سورس باز است.
ولی در کل یک مورد را بیشتر نصب نکنید. علت هم کند شدن VS.Net است به دلیل فعالیت‌های پشت صحنه‌ی هر کدام از این افزونه‌ها که زیاده روی در تعداد آن‌ها گاها باعث کرش هم می‌شود. بنابراین همان یک مورد کافی است.

ز) Import مخزن‌های قبلی
تا اینجا مقدمات کار فراهم شد. اکنون نوبت به import مخزن‌های بجا مانده از سیستم قبلی است. برای اینکار مطابق شکل زیر، گزینه‌ی import existing repositories را انتخاب کرده و مسیر مخزن‌های قبلی خود را باید معرفی نمود (به ازای هر کدام یکبار باید این عملیات صورت گیرد).



پس از انجام این مراحل یکبار باید سیستم reboot شود و اکنون همه چیز مثل قبل خواهد شد!


نکته:
اگر مسیر ریشه مخزن‌های جدید با مسیر آن‌ها در سیستم قبلی متفاوت است، هنگام commit کارهای خود با خطای زیر متوقف خواهید شد:
Commit failed (details follow): Unable to open an ra_local session to URL
Unable to open repository 'file:///C:/Repositories/tracking/trunk'




اشکالی ندارد! برای رفع آن باید از گزینه‌ی relocate مربوط به TortoiseSVN استفاده کرد.
بر روی پوشه کاری پروژه خود کلیک راست کرده، انتخاب گزینه‌ی TortoiseSVN و سپس انتخاب گزینه‌ی Relocate آن باید صورت گیرد. در اینجا می‌توان مسیر جدید ریشه اصلی مخزن را در سیستم جدید معرفی کرد.