Change this section ... <PropertyGroup> <TargetFramework>netcoreapp2.2</TargetFramework> <AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel> </PropertyGroup> to the following ... <PropertyGroup> <TargetFramework>netcoreapp2.2</TargetFramework> <AspNetCoreHostingModel>OutOfProcess</AspNetCoreHostingModel> <AspNetCoreModuleName>AspNetCoreModule</AspNetCoreModuleName> </PropertyGroup>
<Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <TargetFramework>netcoreapp2.1</TargetFramework> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.AspNetCore.App" Version="2.1.4" /> <PackageReference Include="Serilog.AspNetCore" Version="2.1.1" /> <PackageReference Include="Serilog.Sinks.RollingFile" Version="3.3.0" />
public class Program { public static int Main(string[] args) { Log.Logger = new LoggerConfiguration() .MinimumLevel.Debug() .MinimumLevel.Override("Microsoft", LogEventLevel.Information) .Enrich.FromLogContext() .WriteTo.RollingFile("logs/log-{Date}.txt") .CreateLogger(); try { Log.Information("Starting web host"); BuildWebHost(args).Run(); return 0; } catch (Exception ex) { Log.Fatal(ex, "Host terminated unexpectedly"); return 1; } finally { Log.CloseAndFlush(); } } public static IWebHost BuildWebHost(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>() .UseSerilog() // <-- Add this line .Build(); }
ایجاد و توزیع برنامههای جدید AngularJS به همراه تمام وابستگیهای آنها و همچنین رعایت بهترین تجربههای کاری آن، اندکی مشکل است. به همین جهت تیم Angular برنامهای را به نام Angular CLI تدارک دیدهاست که تمام این مراحل را به سادگی هرچه تمامتر مدیریت میکند. ممکن است قالبهای زیادی را در مورد شروع به کار با AngularJS 2.0+ در وب پیدا کنید؛ اما هیچکدام از آنها تمام قابلیتهای Angular CLI را ارائه نمیدهند و همواره چندین قدم عقبتر از تیم Angular هستند. به همین جهت در طی یک سری قصد داریم قابلیتهای گوناگون این ابزار را بررسی کنیم.
Angular CLI چیست؟
ایجاد برنامههای جدید Angular لذت بخش هستند؛ اما ایجاد برنامههایی که از بهترین تجربههای کاری توصیه شدهی توسط تیم Angular پیروی میکنند، به همراه Unit tests هستند و همچنین برای توزیع بهینه سازی شدهاند، بسیار چالش برانگیز میباشند. به همین جهت برنامهی خط فرمانی به نام Angular CLI برای مدیریت این مسایل توسط تیم Angular ایجاد شدهاست، تا توسعه دهندگان بیشتر وقت خود را صرف بهینه سازی کدهای خود کنند تا اینکه درگیر تدارک مسایل جانبی این فریم ورک باشند.
اگر به پروژههای سورس باز ارائه شدهی جهت شروع کار با +AngularJS 2.0 دقت کنید، تعداد بیشماری پروژهی seed، قالبهای آماده، کدساز و غیره را خواهید یافت. اکثر آنها تفاوتهای قابل ملاحظهای را با یکدیگر داشته و در اغلب موارد بهترین تجربههای کاری Angular را نیز رعایت نمیکنند. برای مثال خبری از style guide آن و یا مباحث بهینه سازی ساخت و توزیع لحاظ شدهی در نگارشهای جدید Angular، در آنها نیست.
در اینجا بود که تیم Angular تصمیم گرفت تا در جهت ساماندهی به این وضعیت آشفته، برنامهی Angular CLI را ایجاد کند تا برنامه نویسها به همراه ابزاری باشند که بر اساس بهترین تجربههای کاری Angular تهیه شدهاست؛ سبب ایجاد برنامههایی خواهد شد که یکدست به نظر میرسند و همچنین همواره آخرین تغییرات توزیع و آزمایش برنامهها را نیز به همراه دارد.
پیشنیازهای نصب Angular CLI
پیش از شروع به نصب Angular CLI باید مطمئن شوید که آخرین نگارش NodeJS را نصب کردهاید. برای این منظور خط فرمان را گشوده و دستور ذیل را صادر کنید:
C:\>node -v v5.10.1
اگر این مطلب را در چند ماه بعد پس از نگارش آن مطالعه میکنید، به پروژهی Angular CLI مراجعه کرده و قسمت Prerequisites مستندات ابتدایی آنرا برای مشاهدهی آخرین نگارش NodeJS مورد نیاز آن، بررسی کنید.
نصب Angular CLI
پس از نصب پیشنیاز آن، اکنون خط فرمان را گشوده و دستور ذیل را صادر کنید:
C:\>npm install -g @angular/cli
پس از نصب آن، جهت اطمینان از عملیات انجام شده، دستور ذیل را در خط فرمان صادر کنید:
C:\>npm list -g @angular/cli --depth=0
C:\>npm list -g @angular/cli --depth=0 C:\Users\Vahid\AppData\Roaming\npm `-- @angular/cli@1.0.0
و همچنین برای مشاهدهی نگارش CLI نصب شده، دستور ذیل را اجرا نمائید:
C:\>ng -v _ _ ____ _ ___ / \ _ __ __ _ _ _| | __ _ _ __ / ___| | |_ _| / △ \ | '_ \ / _` | | | | |/ _` | '__| | | | | | | / ___ \| | | | (_| | |_| | | (_| | | | |___| |___ | | /_/ \_\_| |_|\__, |\__,_|_|\__,_|_| \____|_____|___| |___/ @angular/cli: 1.0.0 node: 6.10.2 os: win32 x64
ایجاد یک برنامهی جدید توسط Angular CLI
پس از نصب Angular CLI، اکنون میتوان از آن جهت ساخت یک برنامهی جدید Angular استفاده کرد. برای این منظور یک پوشهی جدید را ایجاد کرده و سپس از طریق خط فرمان به آن وارد شده (نگه داشتن دکمهی shift و سپس کلیک راست و انتخاب گزینهی Open command window here) و دستور ذیل را صادر کنید:
> ng new ngtest --skip-install
در اینجا ساختار یک پروژهی جدید Angular را مشاهده میکنید.
فایل | توضیحات |
.angular-cli.json | تنظیمات cli را به همراه دارد. |
editorconfig | مربوط به تنظیمات VSCode است. |
karma.conf.js | برای انجام unit tests است. |
package.json | وابستگیهای npm برنامه را به همراه دارد (که در زمان نگارش این مطلب تنظیمات Angular 4 را به همراه دارد). |
protractor.conf.js | برای اجرای آزمونهای end to end که در اینجا e2e نام گرفتهاست، میباشد. |
tsconfig.json | تنظیمات کامپایلر TypeScript را به همراه دارد. |
tslint.json | جهت اجرای Lint و ارائهی بهترین تجربههای کاری با TypeScript است. |
داخل پوشهی src، فایلهای اصلی پروژه قرار دارند:
- فایل index.html کار ارائه و شروع برنامه را انجام میدهد.
- فایل main.ts نقطهی آغاز برنامه است.
با توجه به استفادهی از پارامتر skip-install، هنوز وابستگیهای فایل package.json نصب نشدهاند. برای این منظور به پوشهی اصلی پروژه وارد شده (جایی که پوشهی ngtest و فایل package.json قرار دارد) و دستور npm install را صادر کنید تا وابستگیهای برنامه نیز دریافت شوند. البته اگر از پارامتر یاد شده استفاده نمیشد، اینکار به صورت خودکار توسط ng new انجام میگرفت.
>npm install
به این ترتیب وابستگیهای پروژه در پوشهی node_modules تشکیل خواهند شد.
به روز رسانی Angular CLI
روش به روز رسانی AngularCLI شامل این مراحل است:
الف) به روز رسانی بستهی عمومی نصب شدهی آن
npm uninstall -g @angular/cli npm cache clean npm install -g @angular/cli@latest
ب) به روز رسانی یک برنامهی محلی
در ادامه به پوشهی برنامهی خود وارد شده و دستورات ذیل را اجرا کنید:
rm rmdir /S/Q node_modules dist npm install --save-dev @angular/cli@latest npm install
مورد «الف» را به ازای هر نگارش جدید CLI، تنها یکبار باید انجام داد. اما مورد «ب» به ازای هر پروژهی موجود باید یکبار انجام شود (که سریعترین روش به روز رسانی وابستگیهای یک برنامه، به آخرین نگارش Angular است).
پیش نیاز ها:
»Owin چیست
»تبدیل برنامههای کنسول ویندوز به سرویس ویندوز ان تی
برای شروع یک برنامه Console Application ایجاد کرده و اقدام به نصب پکیجهای زیر نمایید:
Install-Package Microsoft.AspNet.WebApi.OwinSelfHost Install-Package TopShelf
حال یک کلاس Startup برای پیاده سازی Configurationهای مورد نیاز ایجاد میکنیم
در این قسمت میتوانید تنظیمات زیر را پیاده سازی نمایید:
»سیستم Routing؛
»تنظیم Dependency Resolver برای تزریق وابستگی کنترلرهای Web Api؛
»تنظیمات hubهای SignalR(در حال حاضر SignalR به صورت پیش فرض نیاز به Owin برای اجرا دارد)؛
»رجیستر کردن Owin Middlewareهای نوشته شده؛
»تغییر در Asp.Net PipeLine؛
»و...
public class Startup { public void Configuration(IAppBuilder appBuilder) { HttpConfiguration config = new HttpConfiguration(); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); appBuilder.UseWebApi(config); } }
در این مرحله یک کنترلر Api به صورت زیر به پروژه اضافه نمایید:
public class ValuesController : ApiController { public IEnumerable<string> Get() { return new string[] { "value1", "value2" }; } public string Get(int id) { return "value"; } public void Post([FromBody]string value) { } public void Put(int id, [FromBody]string value) { } }
public class ServiceHost { private IDisposable webApp; public static string BaseAddress { get { return "http://localhost:8000/"; } } public void Start() { webApp = WebApp.Start<Startup>(BaseAddress); } public void Stop() { webApp.Dispose(); } }
در مرحله آخر باید شروع و توقف سرویسها را تحت کنترل کلاس HostFactory کتابخانه TopShelf در آوریم. برای این کار کافیست کلاسی به نام ServiceHostFactory ایجاد کرده و کدهای زیر را در آن کپی نمایید:
public class ServiceHostFactory { public static void Run() { HostFactory.Run( config => { config.SetServiceName( "ApiServices" ); config.SetDisplayName( "Api Services ]" ); config.SetDescription( "No Description" ); config.RunAsLocalService(); config.Service<ServiceHost>( cfg => { cfg.ConstructUsing( builder => new ServiceHost() ); cfg.WhenStarted( service => service.Start() ); cfg.WhenStopped( service => service.Stop()); } ); } ); } }
با استفاده از متد ConstructUsing عملیات وهله سازی از سرویس انجام خواهد گرفت. در پایان نیز متد Start و Stop کلاس ServiceHost، به عنوان عملیات شروع و پایان سرویس ویندوز مورد نظر تعیین شد.
حال اگر در فایل Program پروژه، دستور زیر را فراخوانی کرده و برنامه را ایجاد کنید خروجی زیر قابل مشاهده است.
ServiceHostFactory.Run();
در حالیکه سرویس مورد نظر در حال اجراست، Browser را گشوده و آدرس http://localhost:8000/api/values/get را در AddressBar وارد کنید. خروجی زیر را مشاهده خواهید کرد:
- توابع خط فرمان - Command Line API
- توابع کنسول - Console API
<div id="first" class="content">Content1 with css class and id</div> <div class="content"> Content2 with css class <a class="links" href="#">Link1</a> <a href="#">Link2</a> </div> <div> Content3 without css class and id </div> <input type="button" onclick="myFunc()" value="Run myFunc" /> <input type="text" id="myInput" /> <script type="text/javascript"> function myFunc() { loop(1000); loop(50000); } function loop(number) { for (var i = 0; i < number; i++) { } } </script>
$$("div.content");
profile("myFunc Testing"); myFunc(); profileEnd();
- $(id)
معادل دستور document.getElementById است که یک المنت با id داده شده بر میگرداند .
$("first");
- $$(selector)
آرایه ای از المنتهای مطابق با selector داده شده بر میگرداند .
$$("div.content")
به تفاوت دو دستور توجه کنید . خروجی دستور اول ، یک المنت است و خروجی دستور دوم یک آرایه از المنت که بین [ و ] قرار گرفته اند .
برای آشنایی بیشتر با CSS Seletorها به این لینک مراجعه کنید : http://www.w3.org/TR/css3-selectors
- $x(xPathExpression)
آرایه ای از المنت هایی را بر میگرداند که با xPath داده شده مطابقت داشته باشند .
var objects = $x("html/body/div[2]/a") for(var i = 0; i < objects.length; i++) { console.log(objects[i]); }
برای آشنایی بیشتر با عبارات xPath به این لینک مراجعه کنید : http://www.w3schools.com/xpath
- dir(object)
تمام خصوصیات شیء ارسال شده را لیست میکند .
var objects = $x("html/body/div[2]/a") dir(objects);
- dirxml(node)
سورس یک المنت را بصورت درختواره ( tree ) پرینت میکند . همچنین با کلیک بروی هر node ، فایرباگ آن node را در تب html نمایش میدهد .
var node = $("first"); dirxml(node);
توجه کنید که این دستور فقط یک node دریافت میکند . برای همین اگر از دستور $$("#first") استفاده میکنید ، چون این دستور یک آرایه بر میگرداند ، باید اولین عضو آرایه را دریافت و ارسال کنید .
یعنی :
var node = $$("#first")[0]; dirxml(node);
- clear()
این دستور محیط console را خالی میکند . عملکرد این دستور معادل کلیک دکمهی Clear ( در بالا - چپ تب کنسول ) است .
- inspect(object[,tabName])
توسط این دستور میتوانید یک شیء را در مناسبترین تب فایرباگ یا یکی از تبهای مورد نظر خود ، Inspect کنید .
var node = $("first"); inspect(node); // inspect in html tab inspect(node,'dom'); // inspect in dom tab
- keys(object)
آرایه ای از "نام" تمام خصوصیات شیء ارسال شده بر میگرداند .
var obj = $("first"); keys(obj)
- values(object)
آرایه ای از "مقدار" تمام خصوصیات شیء ارسال شده بر میگرداند .
var obj = $("first"); values(obj)
- debug(fn) and undebug(fn)
این متدها یک BreakPoint در ابتدای تابع مشخص شده اضافه/حذف میکنند . ( در تب Script ) . به همین ترتیب هنگامی که تابع مورد نظر فراخوانی شود ، در نقطه ای که BreakPoint قرار داده شده توقف خواهد کرد .
البته میشود BreakPoint را دستی هم قرار داد . در اصل این تابع ، این عملیات را سادهتر میکند .
debug(myFunc); myFunc(); undebug(myFunc);
- monitor(fn) and unmonitor(fn)
این متدها برای فعال/غیرفعال کردن Logging فراخوانیهای یک تابع استفاده میشوند .
در حالت عادی برای پی بردن به اینکه یک تابع اجرا میشود یا نه ، در تابع مورد نظر یک alert قرار میدهیم و تست میکنیم . که این روش در برنامه برنامههای بزرگ صحیح نیست . زیرا در این حالت باید بین حجم زیادی کد به دنبال تابع مورد نظر بگردیم و سپس alert را قرار بدهیم و بعد اطمینان از صحت عملکرد تابع مجدد آن را حذف کرد ، که با اتلاف زمان و به خطر انداختن کدها همراه است .
اما با استفاده از این متدها ، تنها نیاز به داشتن اسم تابع داریم ( و نه مکان تابع در کدهای برنامه ) .
تست monitor :
monitor(myFunc); // now click on "Run myFunc" button
unmonitor(myFunc); // now click on "Run myFunc" button
- monitorEvents(object[, types]) and unmonitorEvents(object[, types])
این متدها عملیات Event Logging برای یک شیء را فعال/غیرفعال میکنند . در کنار شیء مورد نظر ، میتوان نوع رویداد را هم به متد ارسال کرد . در این صورت عملیات Logging فقط برای همان گروه رویداد/رویداد ، فعال/غیرفعال میشود .
منظور از گروه رویداد ، مجموعه رویدادهای یک شیء است . مثلا mousemove , moseover , mousedown , ... در گروه mouse قرار میگیرند . یعنی میتوانید با ارسال کلمهی mouse فقط رویدادهای mouse را تحت نظر بگیرید یا اینکه فقط یک رویداد را مشخص کنید ، مثل mousedown .
راه سادهتر فعال کردن Event Logging ، رفتن به تب Html ، راست کلیک کردن بروی المنت مورد نظر و فعال کردن گزینهی Log Events میباشد .
var obj = $("myInput"); monitorEvents(obj,'keypress');
نتیجه پس از فشردن چند دکمهی کیبورد در myInput :
توضیحات بیشتر : http://getfirebug.com/wiki/index.php/MonitorEvents - profile([title]) and profileEnd()
این متدها ، JavaScript Profiler را فعال/غیرفعال میکنند . هنگام فعال کردن میتوانید یک عنوان هم برای پروفایل مشخص کنید . در قسمت قبلی مقاله در مورد این قابلیت توضیحاتی ارائه شد .
سه را برای اجرای Profiler وجود دارد :
1 - کلیک بروی دکمهی Profiler در بالای تب کنسول .
2 - استفاده از کد console.profile("ProfileTitle") در کدهای جاوا اسکریپت .
3 - استفاده از متد profile("Profile Title") در خط فرمان .
profile("myFunc Testing"); myFunc(); profileEnd();
ستونهای Profiler :Function : نام تابع اجرا شده .
Calls : تعداد دفعات فراخوانی تابع .
Percent : زمان اجرای تابع در زمان کل ، به درصد .
Own Time : زمان اجرای تابع به تنهایی . برای مثال در کد ما ، زمان اجرای تابع myFunc به تنهایی تقریبا صفر است زیرا عمیاتی در خود انجام نمیدهد و زمان صرف شده در این تابع ، برای اجرای 2 با تابع loop است . این زمان ( Own Time ) زمان اجرای تابع ، منهای زمان صرف شده برای فراخوانی توابع دیگر است .
Time : زمان اجرای تابع از نقطهی آغاز تا پایان . مجموع زمان اجرای خود تابع به همراه زمان اجرای توابع فراخوانی شده . در کد ما ، این زمان ، مجموع زمان اجرای خود تابع به همراه دو بار فراخوانی تابع loop است .
Avg : میانگین زمان اجرای هربار تابع . فرمول : Avg = Time / Calls
Min & Max : حداقل و حداکثر زمان اجرای تابع .
File : نام فایل و شماره خطی که تابع در آن قرار دارد .