مطالب
آشنایی با ساختار IIS قسمت هفتم

در این قسمت بیشتر یک سری از ماژول‌ها را به شما در قالب جداول گروه بندی شده معرفی خواهیم کرد :

   همانطور که در قسمت‌های قبلی گفتیم سرور IIS آماده خصوصی سازی و کار بر اساس علائق شماست؛ ولی توجه داشته باشید حذف تمامی ماژول‌ها ممکن است اثرات جانبی هم داشته باشد. در اینجا ما ماژول هایی را به شما معرفی می‌کنیم که بدانید کار هر ماژول چیست تا مثلا با حذف ماژولی، امنیت وب سایت خود را به خطر نیندازید :

ماژول‌های سودمند یا utility

نام ماژول:

UriCacheModule

توضیح:

این ماژول نوعی کش برای URLها به شمار می‌رود. موقعی که url درخواست می‌شود، اطلاعات در اولین درخواست خوانده شده و کش می‌شود و اگر دوباره همان url درخواست شود، بدون خواندن تنظیمات و بر اساس تنظیمات قبلی، کار url مربوطه را انجام میدهد تا اطلاعات پیکربندی تغییر کند و بر اساس اطلاعات جدید، خود را به روز کند.

تگ قابل پیکربندی:

لازم ندارد

وابستگی:

ندارد

اثرات حذف آن:

کارایی سیستم کاهش می‌یابد و سیستم مجبور است برای هر درخواست فایل پیکربندی را بخواند.

نام ماژول :

FileCacheModule

توضیح :

فایل هندلِ فایل‌هایی که قبلا در سرور باز شده‌اند را کش می‌کند تا در صورت نیاز در دفعات بعدی سریعتر عمل کند.

تگ قابل پیکربندی :

لازم ندارد .

وابستگی :

ندارد.

اثرات حذف آن :

کارایی سیستم کاهش می‌یابد. سیستم در هر اجرای دستور مربوط به فایل‌ها باید فایل هندل را به دست آورد.

نام ماژول :

TokenCacheModule

توضیح :

توکن‌های امنیتی ویندوز که پسوردهایی بر اساس authentication schemes هستند را کش می‌کند (anonymous authentication, basic authentication, IIS client certificate authentication )

تگ قابل پیکربندی :

لازم ندارد

وابستگی :

ندارد

اثرات حذف آن :

کارایی سیستم به شدت پایین می‌آید. کاربر باید با هر درخواستی لاگین کند. یکی از اصلی‌ترین ضربه‌ها با حذف این ماژول این است که اگر مثلا یک پسورد از یک فایل html محافظت می‌کند و این صفحه به 50 تصویر ارجاع دارد، 51 بار باید درخواست لاگین اجرا گردد یا شاید هم بدتر

MANAGED ENGINE: ASP.NET INTEGRATION

نام ماژول :

ManagedEngine

توضیح :

مدیریت ماژول‌های native و مدیریت شده

تگ قابل پیکربندی :


وابستگی :

ندارد

اثرات حذف آن :

مشخصا غیرفعال شدن asp.net integrated و غیر فعال شدن تمامی ماژول‌ها و هندلر‌های تگ وب کانفیگ یا داخل فایل کانفیگ IIS که در مقالات قبلی به تفصیل بیان کرده‌ایم.

IIS 7 NATIVE MODULES

نام ماژول :

HttpCacheModule

توضیح :

مدیریت کش خروجی در htttp.sys بر اساس پیکربندی مثل تعریف سایز کش و ...

تگ قابل پیکربندی :

System.webServer/caching

وابستگی :

ندارد.

اثرات حذف آن :

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

نام ماژول :

DynamicCompressionModule

توضیح :

پیاده سازی in-memory compression در محتوای پویا

تگ قابل پیکربندی :

system.webServer/httpCompression and system.webServer/urlCompression.

وابستگی :

وابستگی ندارد چرا که به طور پیش فرض غیرفعال است.

نام ماژول :

StaticCompressionModule

توضیح :

پیادسازی فشرده سازی در محتوای ایستا و برای فایل‌های سیستمی از نوع in memory

تگ قابل پیکربندی :

system.webServer/httpCompression and system.webServer/urlCompression

وابستگی :

ندارد.

اثرات حذف آن :

در صورت عدم فشرده سازی بر مصرف ترافیک تاثیر گذار است.

نام ماژول :

DefaultDocumentModule

توضیح :

پیاده سازی یک لیست سند پیش فرض. درخواست‌ها مدام پشت سر هم می‌آیند و این درخواست‌های پشت سرهم، به سند پیش فرض هدایت می‌شوند. همان پنجره ای که شما به ترتیب فایل‌های index.htm,index.asp,default.aspx و... را تعیین می‌کنید.

تگ قابل پیکربندی :

system.webServer/defaultDocument

وابستگی :

ندارد.

اثرات حذف آن :

درخواست را به ریشه هدایت می‌کند. مثلا برای localhost صفحه 404 باز میگرداند و اگر directoryBrowsing فعال باشد لیستی از دایرکتوری ریشه را باز میگرداند.

نام ماژول :

DirectoryListingModule

توضیح :

پیادی سازی لیستی از محتویات یک دایرکتوری

تگ قابل پیکربندی :

system.webServer/directoryBrowse

وابستگی :

ندارد.

اثرات حذف آن :

اگر این ماژول و ماژول قبلی غیرفعال باشند response نهایی خالی است.

نام ماژول :

ProtocolSupportModule

توضیح :

پیاده سازی اختصاصی از response header

پیاده سازی تنظیمات trace و HTTP verbs.

پیاده سازی تنظیمات مربوطه به keep-alive بر اساس پیکربندی

تگ قابل پیکربندی :

system.webServer/httpProtocol

وابستگی :

ندارد.

اثرات حذف آن :

بازگرداندن پیام خطای "405 Method not allowed".

نام ماژول :

HttpRedirectionModule

توضیح :

پیاده سازی عملیات انتقال یا redirect

تگ قابل پیکربندی :

system.webServer/httpRedirect

وابستگی :

ندارد.

اثرات حذف آن :

خطر امنیتی: اگر منابعی با redirect کردن محافظت می‌شوند، از این پس در دسترسند.

نام ماژول :

ServerSideIncludeModule

توضیح :

حمایت از فایل shtm یا shtml و ...

تگ قابل پیکربندی :

system.webServer/serverSideInclude

وابستگی :

ندارد.

اثرات حذف آن :

این فایل‌ها به صورت متنی نمایش داده می‌شوند

نام ماژول :

StaticFileModule

توضیح :

فایل‌های ایستا را به همراه پسوند ارسال می‌کند. مثل jpg,html و نوع محتوا را بر اساس staticContent/mimeMap پیکربندی می‌کند.

تگ قابل پیکربندی :

system.webServer/staticContent

وابستگی :

ندارد.

اثرات حذف آن :

فایل‌های ایستا دیگر ارائه نشده و به جای آن خطای 404 بازگشت داده می‌شود.

نام ماژول :

AnonymousAuthenticationModule

توضیح :

پیاده سازی سیستم شناسایی افراد ناشناس. همانطور که میدانید در یک وب سایت حداقل محتوایی برای افرادی بدون داشتن اکانت هم وجود دارد. برای اینکار یک شیء httpuser ایجاد می‌کند.

تگ قابل پیکربندی :

system.webServer/security/authentication/anonymousAuthentication

وابستگی :

ندارد.

اثرات حذف آن :

حداقل باید یک سیستم امنیتی برای شناسایی یا authenticate وجود داشته باشد. httpuser یک ساختار داده ای در IIS می‌باشد و در صورت نبودن هیچ سیستم شناسایی وجود نداشته و در نبود شیء httpuser سیستم خطای 401.2 را تولید می‌کند.

نام ماژول :

CertificateMappingAuthenticationModule

توضیح :

مجوز SSL را به Active Directory نگاشت می‌کند.

تگ قابل پیکربندی :

system.webServer/security/authentication/clientCertificateMappingAuthentication

وابستگی :

برای اینکه این ماژول وظیفه خود را انجام دهد باید تنظیمات SSL انجام شود و همچنین سیستم IIS جزئی از دامنه Active directory باشد

اثرات حذف آن :

درخواست‌ها، نرمال رسیدگی میشوند انگار SSL وجود ندارد.

نام ماژول :

BasicAuthenticationModule

توضیح :

پیاده سازی پایه‌ای و روتین شناسایی کاربران بر اساس آن چیزی که در استانداد زیر آمده است

RFC 2617.

تگ قابل پیکربندی :

system.webServer/security/authentication/basicAuthentication

وابستگی :

None.

اثرات حذف آن :

حداقل باید یک سیستم امنیتی برای شناساسایی یا authenticate وجود داشته باشد. httpuser یک ساختار داده‌ای در IIS می‌باشد و در صورت نبود، هیچ سیستم شناسایی یافت نشده و نبود شیء  httpuser در سیستم، خطای 401.2 را تولید می‌کند.

نام ماژول :

WindowsAuthenticationModule

توضیح :

((windows Authentication (NTLM or Negotiate (Kerberos

تگ قابل پیکربندی :

system.webServer/security/authentication/windowsAuthentication

وابستگی :

ندارد.

اثرات حذف آن :

حداقل باید یک سیستم امنیتی برای شناسایی یا authenticate وجود داشته باشد. httpuser یک ساختار داده ای در IIS می‌باشد و در صورت نبود، هیچ سیستم شناسایی یافت نشده و نبود شیء httpuser در سیستم، خطای 401.2 را تولید می‌کند.

نام ماژول :

DigestAuthenticationModule

توضیح :

پیاده سازی سیستم شناسایی دیاجست بر اساس

RFC 2617 .

تگ قابل پیکربندی :

system.webServer/security/authentication/digestAuthentication

وابستگی :

IIS باید بخشی از دامنه Active Directory باشد.

اثرات حذف آن :

حداقل باید یک سیستم امنیتی برای شناسایی یا authenticate وجود داشته باشد. httpuser یک ساختار داده ای در IIS می‌باشد و در صورت نبود، هیچ سیستم شناسایی یافت نشده و نبود شیء httpuser در سیستم، خطای 401.2 را تولید می‌کند.

نام ماژول :

IISCertificateMappingAuthenticationModule

توضیح :

پیاده سازی نگاشت مجوزهای IIS، نگهداری و ذخیره اطلاعات همه نگاشت‌ها و مجوزهای کاربری چون SSL client certificates  

تگ قابل پیکربندی :

system.webServer/iisClientCertificateMappingAuthentication

وابستگی :

اطلاعات SSL به همراه دریافت client certificates جهت پیکربندی این ماژول

اثرات حذف آن :

حداقل باید یک سیستم امنیتی برای شناسایی یا authenticate وجود داشته باشد. httpuser یک ساختار داده ای در IIS می‌باشد و در صورت نبود، هیچ سیستم شناسایی یافت نشده و نبود شیء httpuser در سیستم، خطای 401.2 را تولید می‌کند.

نام ماژول :

UrlAuthorizationModule

توضیح :

پیاده سازی authorization بر اساس قوانین پیکربندی شده

تگ قابل پیکربندی :

system.webServer/security/authorization

وابستگی :

ندارد.

اثرات حذف آن :

محتواهای محافظت شده توسط authorization دیگر محافظت نمی‌شوند.

نام ماژول :

IsapiModule

توضیح :

پیاده سازی ISAPI Extension 

تگ قابل پیکربندی :

system.webServer/isapiCgiRestriction

وابستگی :

ندارد.

اثرات حذف آن :

هندلر‌های معرفی شده در بخش IsapiModule و تگ handlers دیگر اجرا نمی‌شوند

نام ماژول :

IsapiFilterModule

توضیح :

پیاده سازی ISAPI filter 

تگ قابل پیکربندی :

system.webServer/isapiFilters

وابستگی :

ندارد.

اثرات حذف آن :

اگر برنامه ای از ISAPI filter استفاده می‌کند، در اجرا دچار مشکل خواهد شد.

نام ماژول :

IpRestrictionModule

توضیح :

یک سیستم تشخیص دسترسی  بر اساس آی پی‌های ورژن4

تگ قابل پیکربندی :

system.webServer/security/ipSecurity

وابستگی :

IPv4 stack باید نصب شود.

اثرات حذف آن :

کلاینت هایی که IP هایشان در IPsecurity لیست شده‌اند ندید گرفته میشوند

نام ماژول :

RequestFilteringModule

توضیح :

پیاده سازی یک مجموعه قدرتمند از قوانین امنیتی که درخواست‌های مشکوک را پس می‌زند.

تگ قابل پیکربندی :

system.webServer/security/requestFiltering

وابستگی :

ندارد.

اثرات حذف آن :

دیگر قوانین امنیتی اجرا نخواهند شد و سبب وجود مشکلات امنیتی میشود.

نام ماژول :

CustomLoggingModule

توضیح :

پیاده سازی اینترفیس ILogPlugin در سمت IIS، به مشتریان اجازه میدهد تا لاگ‌های خود را توسعه دهند. هر چند این روش توصیه نمی‌شود و توصیه کارشناس مایکروسافت استفاده از یک ماژول دست نویس از نوع RQ_LOG_REQUEST می باشد.

Implements the ILogPlugin interface on top of IIS. ILogPlugin is a previous COM implementation that allowed customers to extend IIS logging. We do not not recommend extending IIS using this interface. Instead, customers should write a module and subscribe to the RQ_LOG_REQUEST notification.

تگ قابل پیکربندی :

system.webServer/httpLogging and system.applicationhost/sites/site/logFile/customLogPluginClsid

وابستگی :

ندارد.

اثرات حذف آن :

مسلما پلاگین‌های‌های این اینترفیس از کار می‌‌افتند که سیستم ODBC Logging هم جز آن است.

نام ماژول :

CustomErrorModule

توضیح :

پیاده سازی مدیریت خطاهای ویژه

تگ قابل پیکبرندی :

system.webServer/httpErrors

وابستگی :

None.

اثرات حذف آن :

در صورتی که خطایی از هسته باشد، نتیجه یک صفحه، با توضیح مختصری از خطا خواهد بود. در غیر این صورت اگر خطا از برنامه یا کامپوننتی باشد جزئیات خطا فاش خواهد شد

نام ماژول :

HttpLoggingModule

توضیح :

پیاده سازی سیستم logging استاندارد http.sys

تگ قابل پیکربندی :

system.applicationHost/log and system.webServer/httpLogging

وابستگی :

ندارد.

اثرات حذف آن :

از کار افتادن سیستم لاگ

نام ماژول :

FailedRequestsTracingModule

توضیح :

پیاده سازی سیستم ردیابی درخواست‌های ناموفق و اجرای قوانین، طبق پیکربندی

تگ قابل پیکربندی :

system.webServer/tracing and system.webServer/httpTracing

وابستگی :

ندارد.

اثرات حذف آن :

Tracing http requests will no longer work.

نام ماژول :

RequestMonitorModule

توضیح :

پیاده سازی IIS Run-time State and Control Interface یا به اختصار RSCA . به کاربران اجازه می‌دهد از اطلاعات، حین اجرا، کوئری بگیرند. مثل درخواست درحال اجرای جاری، آغاز به کار یا توقف وب سایت و دامنه‌های اپلیکیشن در حال اجرای جاری

تگ قابل پیکربندی :

ندارد.

وابستگی :

ندارد.

اثرات حذف آن :

ابزارهای مرتبط با این موضوع از کار می‌افتند

نام ماژول :

CgiModule

توضیح :

پیاده سازی CGI در سمت IIS

تگ قابل پیکبرندی :

system.webServer/cgi and system.webServer/isapiCgiRestriction

وابستگی :

ندارد.

اثرات حذف آن :

برنامه‌های CGI متوقف می‌شوند

نام ماژول :

TracingModule

توضیح :

پیاده سازی سیستم ردیابی ETW

تگ قابل پیکربندی :

system.webServer/httpTracing

وابستگی :

ندارد.

اثرات حذف آن :

باعث از کار افتادن سیستم مربوطه می‌شود

نام ماژول :

ConfigurationValidationModule

توضیح :

اعتبارسنجی تنظیمات برنامه ASP.Net که به حالت integrate انتقال یافته است

تگ قابل پیکربندی :

system.webServer/Validation

وابستگی :

ندارد.

اثرات حذف آن :

عدم اعتبارسنجی و در نتیجه عدم نمایش خطاها

MANAGED MODULES:

نام ماژول :

OutputCache

توضیح :

پیاده سازی output caching

تگ قابل پیکربندی :

system.web/caching/outputCache

وابستگی :

نیاز به ManagedEngine .

اثرات حذف آن :

عدم اجرای output cache

نام ماژول :

Session

توضیح :

مدیریت سشن ها

تگ قابل پیکربندی :

system.web/sessionState

وابستگی :

نیاز به ManagedEngine . 

اثرات حذف آن :

سشن‌ها از دسترس خارج می‌شوند.

نام ماژول :

WindowsAuthentication

توضیح :

اینجا 

تگ قابل پیکربندی :

system.web/authentication

وابستگی :

نیاز به ManagedEngine .

اثرات حذف آن :

این حالت قابل اجرا نخواهد بود

نام ماژول :

FormsAuthentication

توضیح :

اینجا 

تگ قابل پیکربندی :

system.web/authentication

وابستگی :

نیاز به ManagedEngine .

اثرات حذف آن :

این حالت قابل اجرا نیست و کاربران مجوز دار هم نمی‌توانند به منابع محافظت شده دسترسی داشته باشند.

نام ماژول :

DefaultAuthentication

توضیح :

اطمینان از وجود شی Authentication در context مربوطه 

تگ قابل پیکربندی :

system.web/authentication

وابستگی :

نیاز به ManagedEngine .  

اثرات حذف آن :

اگر مد Forms authentication انتخاب شده باشد بر روی بعضی از کاربران ناشناس کار نخواهد کرد و رویداد DefaultAuthentication.OnAuthenticate اجرا نخواهد شد.

نام ماژول :

RoleManager

توضیح :

اینجا 

تگ قابل پیکربندی :


وابستگی :

نیاز به ManagedEngine .

اثرات حذف آن :

این قابلیت در دسترس نمی‌باشد

نام ماژول :

UrlAuthorization

توضیح :

اینجا 

تگ قابل پیکربندی :

system.web/authorization.

وابستگی :

نیاز به ManagedEngine .  

اثرات حذف آن :

باعث از کار افتادن asp.net authorization و فاش شدن بعضی اطلاعات و همچنین دیگر تهدیدات امنیتی

نام ماژول :

AnonymousIdentification

توضیح :

اینجا 

تگ قابل پیکربندی :


وابستگی :

نیاز به ManagedEngine . 

اثرات حذف آن :

The anonymous identification feature used by the ASP.NET Profile will not work.

نام ماژول :

Profile

توضیح :

اینجا 

تگ قابل پیکربندی :


وابستگی :

ManagedEngine module must be installed.

اثرات حذف آن :

ASP.Net Profile از کار خواهد افتاد

نام ماژول :

UrlMappingsModule

توضیح :

 تبدیل یک Url واقعی به یک Url کاربرپسند 

تگ قابل پیکبرندی :


وابستگی :

نیاز به ManagedEngine .

اثرات حذف آن :

نگاشت Url‌ها صورت نمی‌گیرد

اشتراک‌ها
مقایسه EntityFrameWork 6 (7) و NHibernate
 There is quite a bit of Entity Framework and NHibernate comparisons on the web already but all of them cover mostly the technical side of the question. In this post, I’ll compare these two technologies from a Domain Driven Design perspective. I’ll step through several code examples and show you how both of these ORMs let you deal with problems. 
مقایسه EntityFrameWork 6 (7) و NHibernate
مطالب
سایت‌های مهمی که از ASP.NET MVC استفاده می‌کنند

عموما استفاده وسیع از نگارش‌های مختلف ASP.NET مربوط به اینترانت‌های شرکت‌های خصوصی و دولتی است. برنامه‌هایی که هیچ وقت رنگ آسمان را هم نخواهند دید و کسی از آمار یا وجود آن‌ها مطلع نخواهد شد. اما در این بین هستند سایت‌های عمومی که از این فناوری‌ها استفاده می‌کنند. مهم‌ترین و پرترافیک‌ترین سایت‌هایی که در حال حاضر از ASP.NET MVC کمک می‌گیرند شامل موارد زیر هستند:
جالب اینجا است که اخیرا سایت msnbc استفاده وسیعی از RavenDB را هم شروع کرده است.

سایر منابع:

سؤال: چگونه تشخیص دهیم یک سایت از ASP.NET MVC استفاده می‌کند؟

ابتدا افزونه Server Spy را نصب کنید. این افزونه می‌تواند وب سروری را که یک سایت هم اکنون مورد استفاده قرار داده، تشخیص دهد. اگر IIS بود، یعنی این سایت از یکی از مشتقات ASP یا ASP.NET استفاده می‌کند. اگر پسوند صفحات به asp ختم شده بود، ASP‌ کلاسیک دهه نود است. در غیراینصورت یا Web forms است یا MVC. در این حالت به سورس صفحه مراجعه کنید. اگر از ViewState خبری نبود یعنی ASP.NET MVC است.
البته این روش در 90 درصد موارد جواب می‌دهد. می‌شود هدر ارسالی وب سرور را کلا تغییر داد. یعنی ضرورتی ندارد که یک سایت استفاده کننده از IIS حتما اعلام کند که از این وب سرور خاص استفاده می‌کند. یا در ASP.NET Web forms می‌شود ViewState را با ترفندهایی حذف کرد. اما ... این مسایل همه گیر نیست و روش‌ ذکر شده شناسایی، در اکثر موارد جواب می‌دهد.

مطالب
مسیریابی در Angular - قسمت اول - معرفی
مسیریابی در +Angular 2 به همراه قابلیت‌های فراوان و ویژه‌ای است که تعدادی از آن‌ها را تابحال در این سایت بررسی کرده‌ایم. مورد مقدماتی اول، نیاز به بازنویسی کامل دارد، مورد دوم جهت آشنایی با ساختار Angular CLI مفید است و مورد سوم یکی از مباحث تکمیلی آن است. به همین جهت در طی یک سری، ویژگی‌های متعدد سیستم مسیریابی +Angular 2 را از ابتدا بررسی خواهیم کرد.


مسیریابی در +Angular 2

عموما از مسیریابی جهت حرکت بین Viewهای مختلف برنامه استفاده می‌شود، اما کارهای بیشتری را نیز می‌توان با آن انجام داد؛ مانند ارسال اطلاعات، به مسیریابی‌ها، پیش بارگذاری اطلاعات، جهت نمایش در Viewها، گروه بندی و محافظت از مسیریابی‌ها، پویانمایی و انیمیشن و همچنین بهبود کارآیی، با بارگذاری async مسیرهای مختلف.
کار سیستم مسیریاب +Angular 2 زمانی شروع می‌شود که تغییری را در آدرس درخواستی از برنامه مشاهده می‌کند؛ یا از طریق درخواست آدرسی توسط مرورگر و یا هدایت به قسمتی خاص، از طریق کدنویسی. سپس مسیریاب به آرایه‌ی تنظیم شده‌ی مسیرهای سیستم مراجعه می‌کند تا بتواند تطابقی را بین آدرس درخواستی و یکی از کلیدهای تنظیم شده‌ی در آن پیدا کند. در این حالت اگر تطابقی یافت نشود، کارمسیریابی خاتمه خواهد یافت. در غیراینصورت کار ادامه یافته و سپس مسیریاب، محافظ‌های مسیر درخواستی را بررسی می‌کند تا مشخص شود که آیا کاربر مجاز به هدایت به این قسمت خاص از برنامه هست یا خیر؟ در صورت مثبت بودن پاسخ، مرحله‌ی بعد، پیش بارگذاری اطلاعات درخواستی جهت نمایش View مرتبط است. در ادامه کامپوننت متناظر با مسیریابی فعالسازی می‌شود. سپس قالب این کامپوننت را در قسمتی که توسط router-outlet مشخص می‌گردد، جایگذاری کرده و نمایش می‌دهد.


تعریف مسیر پایه یا Base path

اولین مرحله‌ی کار با سیستم مسیریابی +Angular 2، تعریف یک base path است. مسیرپایه، به زیرپوشه‌ای اشاره می‌کند که برنامه‌ی ما در آن قرار گرفته‌است:
 www.mysite.com/myapp
در این مثال، مسیرپایه برنامه، /myapp/ است.
مسیریاب از این مسیرپایه جهت ساخت آدرس‌های مسیریابی استفاده می‌کند. مقدار آن نیز به صورت ذیل در فایل index.html برنامه، درست پس از تگ head تعیین می‌گردد:
<!DOCTYPE html>
<html>
<head>
    <base href="/">
در اینجا با ذکر / ، به عنوان مسیرپایه، به ریشه‌ی سایت اشاره شده‌است. اگر برنامه‌ی شما قرار است در یک زیرپوشه قرار بگیرد، در این حالت نحوه‌ی تعیین این زیر پوشه به صورت ذیل خواهد بود:
<base href="/myapp/">


تعیین مسیرپایه جهت ارائه‌ی نهایی

استفاده از مسیر پایه / برای حالت توسعه و همچنین زمانیکه برنامه‌ی نهایی شما در ریشه‌ی سایت توزیع می‌شود، بسیار مناسب است. اما اگر برای حالت توسعه از مقدار / و برای حالت توزیع از مقدار /myapp/ بخواهید استفاده کنید، مدام نیاز خواهید داشت تا فایل index.html نهایی سایت را ویرایش کنید. برای این منظور Angular CLI دارای پرچمی است به نام base-href:
 > ng build --base-href /myapp/
به این ترتیب در زمان ساخت و توزیع نهایی برنامه توسط Angular CLI، کار تنظیم خودکار مسیرپایه نیز صورت خواهد گرفت.
حالت پیش فرض تولید برنامه‌های Angular توسط Angular CLI، تنظیم مسیرپایه در فایل src\index.html به صورت خودکار به / می‌باشد.


تعریف مسیریاب Angular

مسیریاب Angular در ماژولی به نام RouterModule قرار گرفته‌است و باید در ابتدای کار import شود. این ماژول شامل سرویسی است جهت هدایت کاربران به صفحات دیگر و مدیریت URLها، تنظیماتی برای تعریف جزئیات مسیریابی‌ها و تعدادی دایرکتیو که برای فعالسازی و نمایش مسیرها از آن‌ها استفاده می‌شود. برای مثال دایرکتیو RouterLink آن یک المان قابل کلیک HTML را به مسیر و کامپوننتی خاص در برنامه متصل می‌کند. RouterLinkActive، شیوه‌نامه‌ها را به لینک فعال انتساب می‌دهد و RouterOutlet محل نمایش قالب کامپوننت فعال شده را مشخص می‌کند.

یک مثال: در ادامه، یک پروژه‌ی جدید مبتنی بر Angular CLI را به نام angular-routing-lab به همراه تنظیمات ابتدایی مسیریابی آن ایجاد می‌کنیم:
 > ng new angular-routing-lab --routing
به علاوه قصد استفاده‌ی از بوت استرپ را نیز داریم. به همین جهت ابتدا به ریشه‌ی پروژه وارد شده و سپس دستور ذیل را صادر کنید تا بوت استرپ نیز نصب شود و پرچم save آن سبب به روز رسانی فایل package.json نیز گردد:
 > npm install bootstrap --save
پس از آن نیاز است به فایل angular-cli.json. مراجعه کرده و شیوه‌نامه‌ی بوت استرپ را تعریف کنیم:
  "apps": [
    {
      "styles": [
    "../node_modules/bootstrap/dist/css/bootstrap.min.css",
        "styles.css"
      ],
به این ترتیب به صورت خودکار این شیوه نامه به همراه توزیع برنامه حضور خواهد داشت و نیازی به تعریف مستقیم آن در فایل index.html نیست.

در ادامه اگر به فایل src\app\app-routing.module.ts مراجعه کنید، یک چنین محتوایی را خواهید یافت:
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

const routes: Routes = [
  {
    path: '',
    children: []
  }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }
در اینجا برای شروع به کار با سیستم مسیریابی، RouterModule معرفی شده‌است. ابتدا import آن‌را مشاهده می‌کنید و سپس این ماژول به قسمت imports مربوط به NgModule اضافه شده‌است.
می‌توان این قسمت را خلاصه کرد و فایل app-routing.module.ts را نیز حذف کرد و سپس import لازم و تعریف ماژول آن‌را به ماژول آغازین برنامه یا همان src\app\app.module.ts نیز منتقل کرد. اما پس از مدتی تنظیمات مسیریابی آن، فایل ماژول اصلی برنامه را بیش از اندازه شلوغ خواهند کرد. بنابراین Angular-CLI تصمیم به ایجاد یک ماژول مستقل را برای تعریف تنظیمات مسیریابی برنامه گرفته‌است. سپس تعریف آن را به فایل src\app\app.module.ts به صورت خودکار اضافه می‌کند:
import { AppRoutingModule } from './app-routing.module';

@NgModule({
  imports: [
    AppRoutingModule
  ],

اگر به قسمت import مربوط به NgModule فایل src\app\app-routing.module.ts دقت کنید، این ماژول به همراه متد forRoot معرفی شده‌است.
@NgModule({
  imports: [RouterModule.forRoot(routes)],
ماژول مسیریابی به همراه دو متد ذیل است:
الف) forRoot
- کار آن تعریف دایرکتیوهای مسیریابی، مدیریت تنظیمات مسیریابی و ثبت سرویس مسیریابی است.
- نکته‌ی مهم اینجا است که متد forRoot تنها یکبار باید در طول عمر یک برنامه تعریف شود.
- این متد آرایه‌ای از تنظیمات مسیریابی‌های تعریف شده را دریافت می‌کند.
ب) forChild
- کار آن تعریف دایرکتیوهای مسیریابی و مدیریت تنظیمات مسیریابی است؛ اما سرویس مسیریابی را مجددا ثبت نمی‌کند.
- از این متد در جهت تعریف مسیریابی‌های ماژول‌های ویژگی‌های مختلف برنامه و نظم بخشیدن به آن‌ها استفاده می‌شود.

بنابراین زمانیکه از forRoot استفاده می‌شود، سرویس مسیریابی تنها یکبار ثبت خواهد شد و تنها یک وهله از آن موجود خواهد بود. در ادامه هر کدام از ماژول‌های دیگر برنامه می‌توانند forChild خاص خودشان را داشته باشند.

اکنون تمام کامپوننت‌های قید شده‌ی در قسمت declaration، امکان دسترسی به دایرکتیوهای مسیریابی را پیدا می‌کنند. همچنین از آنجائیکه AppRoutingModule به همراه متد forRoot است، سرویس مسیریابی نیز در کل برنامه قابل دسترسی است.


تنظیمات اولیه مسیریابی برنامه

آرایه‌ی const routes: Routes فایل src\app\app-routing.module.ts در ابتدای کار خالی است. در اینجا کار تعریف URL segments و سپس اتصال آن‌ها به کامپوننت‌های متناظری جهت فعالسازی و نمایش قالب آن‌ها صورت می‌گیرد. این نمایش نیز در محل router-outlet تعریف شده‌ی در فایل src\app\app.component.html انجام می‌شود:
<h1>
  {{title}}
</h1>
<router-outlet></router-outlet>
به ازای هر router-outlet، تنها یک مسیر را در هر زمان می‌توان نمایش داد. بنابراین با فعال شدن هر کامپوننت، قالب آن، قالب کامپوننت پیشین را در router-outlet جایگزین خواهد کرد. امکان تعریف router-outletهای دیگری نیز وجود دارند که به آن‌ها secondary routes گفته می‌شود.

در ادامه برای تکمیل مثال جاری، دو کامپوننت جدید خوش‌آمد گویی و همچنین یافتن نشدن مسیرها را به برنامه اضافه می‌کنیم:
>ng g c welcome
>ng g c PageNotFound
که سبب ایجاد کامپوننت‌های src\app\welcome\welcome.component.ts و src\app\page-not-found\page-not-found.component.ts خواهند شد، به همراه به روز رسانی خودکار فایل src\app\app.module.ts جهت تکمیل قسمت declarations آن:
@NgModule({
  declarations: [
    AppComponent,
    WelcomeComponent,
    PageNotFoundComponent
  ],

سپس فایل src\app\app-routing.module.ts را به نحو ذیل تکمیل نمائید:
import { PageNotFoundComponent } from './page-not-found/page-not-found.component';
import { WelcomeComponent } from './welcome/welcome.component';
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

const routes: Routes = [
  { path: 'welcome', component: WelcomeComponent },
  { path: '', redirectTo: 'welcome', pathMatch: 'full' },
  { path: '**', component: PageNotFoundComponent },
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }
در اینجا در ابتدا دو کامپوننت جدید تعریف شده، import شده‌اند.

یک نکته: افزونه‌ی auto import، کار تعریف کامپوننت‌ها را در VSCode بسیار ساده می‌کند و امکان تشکیل خودکار قسمت import را با ارائه‌ی یک intellisense به همراه دارد.

سپس کار تکمیل آرایه‌ی Routes انجام شده‌است. همانطور که مشاهده می‌کنید، این آرایه متشکل است از اشیایی که به همراه خاصیت path و سایر پارامترهای مورد نیاز هستند.
کار خاصیت path، تعیین URL segment متناظری است که این مسیریابی را فعال می‌کند. برای مثال اولین شیء تعریف شده با آدرس‌هایی مانند www.mysite.com/welcome متناظر است.
 { path: 'welcome', component: WelcomeComponent },
در اغلب حالات به همراه path، خاصیت کامپوننت متناظر با آن مسیر نیز ذکر می‌شود؛ مانندWelcomeComponent ایی که در اینجا مقدار دهی شده‌است. هنگامیکه این مسیریابی فعال می‌شود، قالب این کامپوننت‌است که در router-outlet نمایش داده خواهد شد (فایل src\app\welcome\welcome.component.html).

چند نکته:
- در حین تعریف مقدار خاصیت path، هیچ / آغاز کننده‌ای تعریف نشده‌است.
- مقدار خاصیت path، حساس به کوچکی و بزرگی حروف است.
- WelcomeComponent تعریف شده، یک رشته نیست و ارجاعی را به کامپوننت مرتبط دارد. به همین جهت نیاز به import statement ابتدایی را دارد و وجود آن توسط کامپایلر بررسی می‌شود.


تعیین مسیریابی پیش فرض سایت

اما زمانیکه برنامه برای بار اول بارگذاری می‌شود، چطور؟ در این حالت هیچ URL segment ایی وجود ندارد. بنابراین برای تنظیم مسیرپیش فرض سایت، خاصیت path، به یک رشته‌ی خالی همانند دومین شیء تنظیمات مسیریابی، تنظیم می‌شود:
   { path: '', redirectTo: 'welcome', pathMatch: 'full' },
در اینجا زمانیکه کاربر، ریشه‌ی سایت را درخواست می‌کند، به کامپوننت welcome هدایت خواهد شد. در این تنظیم خاصیت pathMatch نحوه‌ی تطابق با خاصیت path را مشخص می‌کند. مقدار full نیز به این معنا است که اگر تمام URL segment دریافتی خالی بود، از این تنظیم استفاده کن.


مدیریت مسیریابی آدرس‌های ناموجود در سایت

تنظیم سومی را نیز در اینجا مشاهده می‌کنید:
 { path: '**', component: PageNotFoundComponent },
** به این معنا است که اگر مسیریاب موفق به تطابق URL segment دریافتی، با هیچکدام از pathهای تعریف شده نبود، از این تنظیم استفاده کند (catch all). برای مثال اگر کاربر آدرس www.mysite.com/someAddr را درخواست کند، چون URL segment آن در آرایه‌ی تنظیمات، تعریف نشده‌است، می‌خواهیم یک صفحه‌ی یافت نشد را نمایش دهیم.

یک نکته: ترتیب مسیریابی‌ها در آرایه‌ی تعریف آن‌ها اهمیت دارد. در اینجا از استراتژی «اولین تطابق یافته‌، برنده خواهد بود» استفاده می‌شود. بنابراین تنظیم ** باید در انتهای لیست ذکر شود؛ در غیراینصورت هیچکدام از مسیریابی‌های تعریف شده‌ی پس از آن پردازش نخواهند شد.


مدیریت تغییرات آدرس‌های برنامه

در طول عمر برنامه ممکن است نیاز به تغییر آدرس‌های برنامه باشد. برای مثال بجای مسیر welcome مسیر home نمایش داده شود:
const routes: Routes = [
  { path: 'home', component: WelcomeComponent },
  { path: 'welcome', redirectTo: 'home', pathMatch: 'full' },
  { path: '', redirectTo: 'welcome', pathMatch: 'full' },
  { path: '**', component: PageNotFoundComponent }
];
در این تنظیمات جدید برنامه، مسیر home به WelcomeComponent اشاره می‌کند. اما جهت هدایت آدرس‌های قدیمی welcome، به این آدرس جدید home می‌توان از redirectTo، مانند دومین شیء مسیریابی اضافه شده‌ی به آرایه‌ی تنظیمات استفاده کرد. به این ترتیب هم تغییرات آرایه‌ی Routes به حداقل می‌رسد و هم آدرس‌های ذخیره شده‌ی توسط کاربران هنوز هم معتبر خواهند بود.

نکته: redirectToها قابلیت تعریف زنجیره‌ای را ندارند. به این معنا که اگر ریشه‌ی سایت درخواست شود، ابتدا به مسیر welcome هدایت خواهیم شد. مسیر welcome هم یک redirectTo دیگر به مسیر home را دارد. اما در اینجا کار به این redirectTo دوم نخواهد رسید و این پردازش، زنجیره‌ای نیست. بنابراین مسیریابی پیش‌فرض را نیز باید ویرایش کرد و به home تغییر داد:
const routes: Routes = [
  { path: 'home', component: WelcomeComponent },
  { path: 'welcome', redirectTo: 'home', pathMatch: 'full' },
  { path: '', redirectTo: 'home', pathMatch: 'full' },
  { path: '**', component: PageNotFoundComponent }
];
به این ترتیب دیگر درخواست زنجیره‌وار redirectToها رخ نخواهد داد.

نکته: redirectToها می‌توانند local و یا absolute باشند. تعریف محلی آن‌ها مانند ذکر home و welcome در اینجا است و تنها سبب تغییر یک URL segment می‌شود. اما اگر در ابتدای مقادیر redirectToها یک / قرار دهیم، به معنای تعریف یک مسیر مطلق است و کل URL را جایگزین می‌کند.


تعیین محل نمایش قالب‌های کامپوننت‌ها

زمانیکه یک کامپوننت فعالسازی می‌شود، قالب آن در router-outlet نمایش داده خواهد شد. برای این منظور فایل src\app\app.component.html را گشوده و به نحو ذیل تغییر دهید:
<nav class="navbar navbar-default">
  <div class="container-fluid">
    <a class="navbar-brand">{{title}}</a>
    <ul class="nav navbar-nav">
      <li>
        <a [routerLink]="['/home']">Home</a>
      </li>
    </ul>
  </div>
</nav>
<div class="container">
  <router-outlet></router-outlet>
</div>
در اینجا دایرکتیو router-outlet محلی است که قالب کامپوننت فعالسازی شده، نمایش داده می‌شود. برای مثال اگر کاربر بر روی لینک Home کلیک کند، کامپوننت متناظر با آن از طریق تنظیمات مسیریابی یافت شده و فعالسازی می‌شود و سپس قالب آن در محل router-outlet رندر خواهد شد.

یک نکته: چون کامپوننت welcome از طریق مسیریابی نمایش داده می‌شود و دیگر به صورت مستقیم با درج تگ selector آن در صفحه فعالسازی نخواهد شد، می‌توان به تعریف کامپوننت آن مراجعه کرده و selector آن‌را حذف کرد.
 @Component({
//selector: 'app-welcome',
templateUrl: './welcome.component.html',
styleUrls: ['./welcome.component.css']
})

تا اینجا اگر دستور ng serve -o را صادر کنیم (کار build درون حافظه‌ای جهت محیط توسعه و نمایش خودکار برنامه در مرورگر)، چنین خروجی در مرورگر نمایان خواهد شد:


اگر به آدرس تنظیم شده‌ی در مرورگر دقت کنید، http://localhost:4200/home آدرسی است که در ابتدای نمایش سایت نمایان خواهد شد. علت آن نیز به تنظیم مسیریابی پیش فرض سایت برمی‌گردد.
و اگر یک مسیر غیرموجود را درخواست دهیم، قالب کامپوننت PageNotFound ظاهر می‌شود:



هدایت کاربران به قسمت‌های مختلف برنامه

کاربران را می‌توان به روش‌های مختلفی به قسمت‌های گوناگون برنامه هدایت کرد؛ برای مثال با کلیک بر روی المان‌های قابل کلیک HTML و سپس اتصال آن‌ها به کامپوننت‌های برنامه. استفاده‌ی کاربر از bookmark مرورگر و یا ورود مستقیم و دستی آدرس قسمتی از برنامه و یا کلیک بر روی دکمه‌های forward و back مرورگر. تنها مورد اول است که نیاز به تنظیم دارد و سایر قسمت‌ها به صورت خودکار مدیریت خواهند شد. نمونه‌ی آن‌را نیز با تعریف لینک Home پیشتر مشاهده کردید:
  <a [routerLink]="['/home']">Home</a>
- در اینجا با استفاده از یک دایرکتیو ویژه به نام routerLink، المان‌های قابل کلیک HTML را به خاصیت‌های path تعریف شده‌ی در تنظیمات مسیریابی برنامه متصل می‌کنیم. routerLink یک attribute directive است؛ بنابراین می‌توان آن‌را به یک المان قابل کلیک anchor tag، مانند مثال فوق نسبت داد.
- زمانیکه کاربر بر روی این لینک کلیک می‌کند، اولین path متناظر با routerLink یافت شده و فعالسازی خواهد شد.
- علت تعریف مقدار routerLink به صورت [] این است که آرایه‌ی پارامترهای لینک را مشخص می‌کند. بنابراین چون آرایه‌است، نیاز به [] دارد. اولین پارامتر این آرایه مفهوم root URL segment را دارد. در اینجا حتما نیاز است URL segment را با یک / شروع کرد. به علاوه باید دقت داشت که خاصیت path تنظیمات مسیریابی، حساس به حروف کوچک و بزرگ است. بنابراین این مورد را باید در اینجا نیز مدنظر داشت.
- پارامترهای دیگر routerLink می‌توانند مفهوم پارامترهای این segment و یا حتی segments دیگری باشند.

یک نکته: چون در مثال فوق، آرایه‌ی تعریف شده تنها دارای یک عضو است، آن‌را می‌توان به صورت ذیل نیز خلاصه نویسی کرد (one-time binding):
 <a routerLink="/home">Home</a>


تفاوت بین آدرس‌های HTML 5 و Hash-based

زمانیکه مسیریاب Angular کار پردازش آدرس‌های رسیده را انجام می‌دهد، اینکار در سمت کلاینت صورت می‌گیرد و تنها URL segment مدنظر را تغییر داده و این درخواست را به سمت سرور ارسال نمی‌کند. به همین جهت سبب reload صفحه نمی‌شود. دو روش در اینجا جهت مدیریت سمت کلاینت آدرس‌ها قابل استفاده است:
الف) HTML 5 Style
- آدرسی مانند http://localhost:4200/home، یک آدرس به شیوه‌ی HTML 5 است. در اینجا مسیریاب Angular با استفاده از HTML 5 history pushState سبب به روز رسانی History مرورگر شده و آدرس‌ها را بدون ارسال درخواستی به سمت سرور، در همان سمت کلاینت تغییر می‌دهد.
- این روش حالت پیش فرض Angular است و نحوه‌ی نمایش آن بسیار طبیعی به نظر می‌رسد.
- در اینجا URL rewriting سمت سرور نیز جهت هدایت آدرس‌ها، به برنامه‌ی Angular ضروری است. برای مثال زمانیکه کاربری آدرس http://localhost:4200/home را مستقیما در مرورگر وارد می‌کند، این درخواست ابتدا به سمت سرور ارسال خواهد شد و چون چنین صفحه‌ای در سمت سرور وجود ندارد، پیغام خطای 404 را دریافت می‌کند. اینجا است که URL rewriting سمت سرور به فایل index.html برنامه، جهت مدیریت یک چنین حالت‌هایی ضروری است.
برای نمونه اگر از وب سرور IIS استفاده می‌کنید، تنظیم ذیل را به فایل web.config در قسمت system.webServer اضافه کنید (کار کرد آن هم وابسته‌است به نصب و فعالسازی ماژول URL Rewrite بر روی IIS):
<rewrite>
    <rules>
        <rule name="Angular 2+ pushState routing" stopProcessing="true">
            <match url=".*" />
                <conditions logicalGrouping="MatchAll">
                    <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
                    <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
                    <add input="{REQUEST_FILENAME}" pattern=".*\.[\d\w]+$" negate="true" />
                    <add input="{REQUEST_URI}" pattern="^/(api)" negate="true" />
                </conditions>
                <action type="Rewrite" url="/index.html" />
        </rule>
    </rules>
</rewrite>

ب) Hash-based
- آدرسی مانند http://localhost:4200/#/home یک آدرس به شیوه‌ی Hash-based بوده و مخصوص مرورگرهایی است بسیار قدیمی که از HTML 5 پشتیبانی نمی‌کنند. اینبار قطعات قرار گرفته‌ی پس از علامت # دارای نام URL fragments بوده و قابلیت پردازش در سمت کلاینت را دارا می‌باشند.
- اگر علاقمند به استفاده‌ی از این روش هستید، نیاز است خاصیت useHash را به true تنظیم کنید:
@NgModule({
   imports: [RouterModule.forRoot(routes, { useHash: true })],
-  این روش نیازی به URL rewriting سمت سرور ندارد. از آنجائیکه سرور هرچیزی را که پس # باشد ندید خواهد گرفت و سعی در یافتن آن‌، در سمت سرور نخواهد کرد.
اشتراک‌ها
Autofac 5.0 منتشر شد

This is the first major-version release we’ve had in about three years (Autofac 4.0 was released in August 2016). There are some breaking changes and new features you should know about as you decide your upgrade strategy. Hopefully this will help you navigate those waters. 

Autofac 5.0 منتشر شد
مطالب
ایجاد نصاب یک قالب پروژه جدید چند پروژه‌ای در ویژوال استودیو
در ویژوال استودیو ذیل منوی File، گزینه‌ای وجود دارد به نام  Export template که کار آن تهیه یک قالب، بر اساس ساختار پروژه جاری است. این قابلیت جهت تهیه قالب‌های سفارشی، برای کاهش زمان تهیه پروژه‌ها بسیار مفید است. به این ترتیب می‌توان بسیاری از نکات مدنظر را، در یک قالب ویژه لحاظ کرد و به دفعات بدون نیاز به copy/paste مداوم فایل‌ها و تنظیمات اولیه، بسیار سریع یک پروژه جدید دلخواه را ایجاد نمود.
اما ... این قالب تهیه شده، صرفا بر اساس یکی از چندین پروژه Solution جاری تهیه می‌شود و همچنین نصب و توزیع آن نیز دستی است. در ادامه قصد داریم با نحوه تهیه یک قالب جدید پروژه متشکل از چندین پروژه، به همراه تهیه فایل VSI نصاب آن، آشنا شویم.


تهیه یک ساختار نمونه

یک پروژه جدید کنسول را به نام MyConsoleApplication ایجاد کنید. سپس به Solution جاری، یک Class library جدید را به نام مثلا MyConsoleApplication.Tests اضافه نمائید. تا اینجا به شکل زیر خواهیم رسید:


اکنون قصد داریم از این پروژه خاص، یک قالب تهیه کنیم؛ تا هربار نخواهیم یک چنین مراحلی را تکرار کنیم.


تهیه قالب به ازای هر پروژه در Solution

در همین حال که Solution باز است، به منوی File و گزینه Export template مراجعه کنید.


در اینجا تنها امکان انتخاب یک پروژه وجود دارد. به همین جهت این مرحله را باید به ازای هر تعداد پروژه موجود در Solution یکبار تکرار کرد.


اکنون در پوشه My Documents\Visual Studio 2010\My Exported Templates دو فایل zip به نام‌های MyConsoleApplication.zip و MyConsoleApplication.Tests.zip وجود دارند. هر دو فایل را توسط برنامه‌های مخصوص گشودن فایل‌های Zip گشوده و تبدیل به دو پوشه باز شده MyConsoleApplication و MyConsoleApplication.Tests کنید.



افزودن فایل MyTemplate.vstemplate چند پروژه‌ای

در همین پوشه جاری که اکنون حاوی دو پوشه باز شده است، یک فایل متنی جدید را با محتوای ذیل به نام MyTemplate.vstemplate ایجاد کنید:
<VSTemplate Version="3.0.0" Type="ProjectGroup"
xmlns="http://schemas.microsoft.com/developer/vstemplate/2005">
  <TemplateData>
    <Name>MyConsoleApplication</Name>
    <Description>MyConsoleApplication Desc</Description>
    <ProjectType>CSharp</ProjectType>
  </TemplateData>
  <TemplateContent>
    <ProjectCollection>
      <ProjectTemplateLink ProjectName="MyConsoleApplication">
      MyConsoleApplication\MyTemplate.vstemplate</ProjectTemplateLink>
      <ProjectTemplateLink ProjectName="MyConsoleApplication.Tests">
      MyConsoleApplication.Tests\MyTemplate.vstemplate</ProjectTemplateLink>
    </ProjectCollection>
  </TemplateContent>
</VSTemplate>
در اینجا به ازای هر پروژه، یک ProjectTemplateLink ایجاد خواهد شد که به فایل MyTemplate.vstemplate موجود در قالب آن اشاره می‌کند.
در ادامه این دو پوشه باز شده و فایل MyTemplate.vstemplate فوق را انتخاب کرده:


و همگی را تبدیل به یک فایل zip جدید کنید؛ مثلا به نام MyConsoleApplicationTemplates.zip.


تهیه فایل نصاب از قالب پروژه جدید

تا اینجا موفق شدیم، چندین قالب پروژه تهیه شده را به هم متصل کرده و تبدیل به یک فایل zip نهایی کنیم. مرحله بعد ایجاد فایلی است متنی به نام MyConsoleApplicationTemplates.vscontent با محتویات زیر:
<VSContent xmlns="http://schemas.microsoft.com/developer/vscontent/2005">
  <Content>
    <FileName>MyConsoleApplicationTemplates.zip</FileName>
    <DisplayName>MyConsoleApplication</DisplayName>
    <Description>A C# project that ...</Description>
    <FileContentType>VSTemplate</FileContentType>
    <ContentVersion>1.0</ContentVersion>
    <Attributes>
      <Attribute name="ProjectType" value="Visual C#" />
      <Attribute name="ProjectSubType" value="Web" />
      <Attribute name="TemplateType" value="Project" />
    </Attributes>
  </Content>
</VSContent>
در اینجا توسط قسمت Attributes مشخص می‌کنیم که قالب پروژه جدید باید در صفحه new project، در کدام مدخل قرار گیرد. بنابراین مطابق تنظیمات فوق، قالب جدید ذیل پروژه‌های وب سی‌شارپ قرار خواهد گرفت. مقدار FileName آن دقیقا معادل نام فایل zip ایی است که در مرحله قبل ایجاد کردیم.

مرحله بعد انتخاب دو فایل MyConsoleApplicationTemplates.vscontent و MyConsoleApplicationTemplates.zip و تبدیل ایندو به یک فایل zip جدید است. پس از ایجاد فایل جدید، پسوند آن‌را به VSI تغییر دهید؛ برای مثال نام آن‌را به MyConsoleApplicationTemplates.vsi تغییر دهید. اکنون این فایل نهایی با دوبار کلیک بر روی آن قابلیت اجرا و نصب خودکار را پیدا می‌کند.


پس از نصب، بلافاصله ذیل قسمت پروژه‌های وب قابل دسترسی و استفاده خواهد بود:



بنابراین به صورت خلاصه:
1) به ازای هر پروژه، یک فایل قالب zip معادل آن باید تهیه شود.
2) تمام این فایل‌های zip را گشوده و تبدیل به پوشه‌های متناظری کنید.
3) یک فایل MyTemplate.vstemplate را در پوشه ریشه مرحله 2 جهت تعریف ProjectTemplateLink‌ها اضافه کنید.
4) فایل جدید MyTemplate.vstemplate مرحله 3 و تمام پوشه‌های قالب‌های باز شده مرحله 2 را zip کنید.
5) سپس یک فایل vscontent نصاب را تهیه و آن‌را با فایل zip مرحله 4 مجددا zip کرده و پسوند آن‌را به VSI تغییر دهید.
اکنون می‌توان این فایل VSI را توزیع کرد.
نظرات مطالب
اجبار به استفاده‌ی از HTTPS در حین توسعه‌ی برنامه‌های ASP.NET Core 2.1
یک نکته‌ی تکمیلی: منقضی شدن مجوز آزمایشی
اگر مجوز آزمایشی مطرح شده‌ی در این مطلب منقضی شود، یک چنین پیام خطایی را با اجرای dotnet run دریافت خواهید کرد:
System.InvalidOperationException: Unable to configure HTTPS endpoint. No server certificate was specified, and the default developer certificate could not be found.
To generate a developer certificate run 'dotnet dev-certs https'. To trust the certificate (Windows and macOS only) run 'dotnet dev-certs https --trust'.
For more information on configuring HTTPS see https://go.microsoft.com/fwlink/?linkid=848054.
و یا حتی با نصب یک نگارش جدید SDK ممکن است خطای زیر را در مرورگر مشاهده کنید:
Secure Connection Failed
An error occurred during a connection to localhost:5001. Certificate key usage inadequate for attempted operation.
Error code: SEC_ERROR_INADEQUATE_KEY_USAGE
برای رفع آن دو دستور زیر را با دسترسی مدیریتی صادر کنید:
dotnet dev-certs https --clean
dotnet dev-certs https --trust
دستور اول مجوز موجود را حذف می‌کند و دستور دوم مجوز جدیدی را تولید و نصب خواهد کرد.
پس از اجرای این دستورات، هم برنامه و هم مرورگر را باید یکبار بسته و بار دیگر از ابتدا اجرا کنید؛ تا مجوزهای جدید را دریافت کنند.
نظرات مطالب
استفاده از Full text search توسط Entity Framework
چند نکته بسیار مهم درباره قابلت  Full Text Search که دوستان باید مد نظر داشته باشند عبارتست : 
1- ابتدا باید در هنگام نصب این قابلیت را در SQL Server فعال کرده باشید 

2- برای اینکه بتوان بر روی ستون‌های مورد نظر Full text Serach زد باید index‌های لازم و همچنین کاتولوگ‌های لازم را تعریف نمود.

//ایجاد کاتالوگ 
 use AdventureWorks
 create fulltext catalog FullTextCatalog as default

 select *
 from sys.fulltext_catalogs

//تعریف ایندکس بر روی ستون  مورد نظر
 create fulltext index on Production.ProductDescription(Description)
 key index PK_ProductDescription_ProductDescriptionID

3- توجه داشته باشید برای حجم داده‌های کم قابلیت Full text Search بسیار کند و زمان بر‌تر از جست و جوهای پایه نظیر استفاده از Like می‌باشد و زمانی که حجم داده‌ها زیاد می‌باشد باید از قابلیت  Full text Search استفاده شود

4- خروجی جست وجوی Full Text Search و جست و جوی معمولی برای داده‌های زیاد یکسان نمی‌باشد ، کافی است در یک دیتا بیس با حجم بالای داده‌ها جست و جو را با هر دو روش انجام دهید ، آن وقت خواهید دید که جست و جوی سنتی (نظیر استفاده از دستور  LIKE) بسییار دقیق‌تر می‌باشد و تمامی اطلاعات خواسته شده را درست بر خواهد گرداند، امام با استفاده از Full Text Search این اطلاعات کامل نمی‌باشد! کافی است خودتان امتحان کنید 

مطالب
استفاده از #F در پروژه های WPF
در دوره #F این سایت (^) با نحوه کد نویسی و مفاهیم و مزایای این زبان آشنا شده اید. اما دانستن syntax یک زبان برای پیاده سازی یک پروژه کافی نیست و باید با تکنیک‌های مهم دیگر از این زبان آشنا شویم. همان طور که قبلا (فصل اول دوره #F) بیان شد Visual Studio به صورت Visual از پروژه‌های #F پشتیبانی نمی‌کند. یعنی امکان ایجاد یک پروژه WPF یا Windows Application یا حتی پروژه‌های تحت وب برای این زبان همانند زبان #C به صورت Visual در VS.Net تعبیه نشده است. حال چه باید کرد؟ آیا باید در این مواقع این گونه پروژه‌ها را با یک زبان دیگر نظیر #C ایجاد کنیم و از زبان #F در حل برخی مسائل محاسباتی و الگوریتمی استفاده کنیم. این اولین راه حلی است که به نظر می‌رسد. اما در حال حاضر افزونه هایی، توسط سایر تیم‌های برنامه نویسی تهیه شده اند که پیاده سازی و اجرای یک پروژه تحت ویندوز یا وب را به صورت کامل با زبان #F امکان پذیر می‌کنند. در  این پست به بررسی یک مثال از پروژه WPF به کمک این افزونه‌ها می‌پردازیم.

نکته : آشنایی با کد نویسی و مفاهیم #F برای درک بهتر مطالب توصیه می‌شود.

معرفی پروژه FSharpX

پروژه FSharpx یک پروژه متن باز است که توسط یک تیم بسیار قوی از برنامه نویسان #F در حال توسعه می‌باشد. این پروژه شامل چندین زیر پروژه و بخش است که هر بخش آن برای یکی از مباحث دات نت در #F تهیه و توسعه داده می‌شود.
این قسمت‌ها عبارتند از :
FSharpx.Core : شامل مجموعه ای کامل از توابع عمومی، پرکاربرد و ساختاری است که برای این زبان توسعه داده شده اند و با تمام زبان‌های دات نت سازگاری دارند؛
FSharpx.Http : استفاده از #F در برنامه نویسی مدل Http؛
FSharpx.TypeProvider : این پروژه خود شامل چندین بخش است که در این جا چند مورد از آن‌ها را عنوان می‌کنم:
  • FSharpx.TypeProviders.AppSetting : متد خواندن و نوشتن (setter  و getter) را برای فایل‌های تنظیمان پروژه (Application Setting File) فراهم می‌کند.
  • FSharpx.TypeProviders.Vector : برای محاسبات با ساختار‌های برداری استفاده می‌شود.
  • FSharpx.TypeProviders.Machine : برای دسترسی و اعمال تغییرات در رجیستری و فایل‌های سیستمی استفاده می‌شود.
  • FSharpx.TypeProviders.Xaml : با استفاده از این افزونه می‌توانیم از فایل‌های Xaml، در پروژه‌های #F استفاده کنیم و WPF Designer نرم افزار VS.Net هم برای این زبان قابل استفاده خواهد شد.
  • FSharpx.TypeProviders.Regex : امکان استفاده از عبارات با قاعده را در این پروژه فراهم می‌کند.

یک مثال از عبارات با قاعده:

type PhoneRegex = Regex< @"(?<AreaCode>^\d{3})-(?<PhoneNumber>\d{3}-\d{4}$)">

PhoneRegex.IsMatch "425-123-2345"
|> should equal true

PhoneRegex().Match("425-123-2345").CompleteMatch.Value
|> should equal "425-123-2345"

PhoneRegex().Match("425-123-2345").PhoneNumber.Value
|> should equal "123-2345"
َشروع پروژه
ایتدا یک پروژه از نوع F# Console Application ایجاد کنید. از قسمت Project Properties (بر روی پروژه کلیک راست کنید و گزینه Properties را انتخاب کنید) نوع پروژه را به Windows Application تغییر دهید(قسمت Out Put Type). اسمبلی‌های زیر را به پروژه ارجاع دهید:
  • PresentationCore
  • PresentationFramework
  • WindowBase
  • System.Xaml

با استفاده از پنجره Package Manager Console دستور نصب زیر را اجرا کنید(آخرین نسخه این پکیج 1.8.31  و حجم آن کمتر از یک مگابایت است):

PM> Install-Package FSharpx.TypeProviders.Xaml

حال یک فایل Xaml به پروژه اضافه کنید و کد‌های زیر را در آن کپی کنید:

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="WPF F# Sample By Masoud Pakdel" Height="350" Width="525">
    <Grid Name="MainGrid">
        <StackPanel Name="StackPanel1" Margin="50">
            <Button Name="Button1">Who are you?</Button>        
        </StackPanel>
    </Grid>
</Window>
کد‌های بالا کاملا واضح است و نیاز به توضیح دیده نمی‌شود. اما اگر دقت کنید می‌بینید که این فایل، فایل Code Behind ندارد. برای این کار باید یک فایل جدید از نوع F# Source File ایجاد کنید. بهتر است که فایل جدید شما همنام با همین فایل باشد. پسوند این فایل fs است. حال کد‌های زیر را در آن کپی کنید:
open System
open System.Windows
open System.Windows.Controls
open FSharpx
 
type MainWindow = XAML<"MainWindow.xaml">
 
let loadWindow() =
    let window = MainWindow()
    window.Button1.Click.Add(fun _ ->
        MessageBox.Show("Masoud Pakdel")
        |> ignore)
    window.Root
 
[<STAThread>]
(new Application()).Run(loadWindow())
|> ignore
نوع XAML استفاده شده  که به صورت generic است در فضای نام FSharpx تعبیه شده است و این اجازه را می‌دهد که یک فایل #F بتواند برای مدیریت یک فایل Xaml  استفاده شود.برای مثال می‌توانید به اشیا و خواص موجود در فایل Xaml دسترسی داشته باشید. در اینجا دیگر خبری از متد InitializeComponent موجود در سازنده کلاس CodeBehind پروژه‌های #C نیست. این تعاریف و آماده سازی کامپوننت‌ها به صورت توکار در نوع XAML موجود در FSharpx انجام می‌شود.


در تابع loadWindow یک نمونه از کلاس MainWindow ساخته می‌شود و برای button1 آن رویداد کلیک تعریف می‌کنیم. دستورات زیر معادل دستورات شروع برنامه در فایل program پروژه‌های #C است.
[<STAThread>]
(new Application()).Run(loadWindow())
|> ignore

پروژه را اجرا کنید و بر روی تنهای Button موجود در صفحه، کلیک کنید و پیغام مورد نظر را مشاهده خواهید کرد. به صورت زیر:

اشتراک‌ها
شاید مایکروسافت با واتس آپ روی اپلیکیشنی از نوع UWP کار کنند

WhatsApp for Windows Phone is one of the few apps on Windows 10 Mobile today that continues to receive frequent updates from its developer. Unfortunately, the app itself is one based on Silverlight, which is what apps built for Windows Phone 8.1 used back in 2014. This means the app isn't a Universal Windows Platform app (UWP,) and as such doesn't run across all the different Windows 10 platforms and devices available today. 

شاید مایکروسافت با واتس آپ روی اپلیکیشنی از نوع UWP کار کنند