اشتراکها
آینده پلتفرم های برنامه نویسی
مراحل ارتقاء پروژههای Angular از نگارش 6 به 7 آن به شرح زیر هستند:
1- به روز رسانی Angular CLI
ابتدا نیاز است نگارش قبلی را حذف و سپس نگارش جدید را نصب کنید:
npm uninstall -g @angular/cli npm cache verify # if npm version is < 5 then use `npm cache clean` npm install -g @angular/cli@latest
البته Angular 7 پشتیبانی از Node 10 را اضافه کرده است (بیشتر؛ دانلود Node). بنابراین پیش از اجرای دستورات فوق بهتر است NodeJS خود را نیز به روز کنید:
npm i -g npm
2- به روز رسانی RxJS (اگر در نگارش 6 آنرا تکمیل نکردهاید)
1-تعویض کردن HttpModule با HttpClientModule و سرویس Http با سرویس HttpClient 2-حذف کردن ویژگیهای منسوخ شده از RxJS 6 با اجرای دستور زیر:
npm install -g rxjs-tslint rxjs-5-to-6-migrate -p src/tsconfig.app.json
3-حذف rxjs-compat بعد از بروزرسانی RxJS 6
اطلاعات بیشتر: «ارتقاء به Angular 6: بررسی تغییرات RxJS»
3- به روز رسانی TypeScript
Angular 7 از تایپ اسکریپت 3.1 استفاده میکند (بیشتر). به همین جهت نیاز است وابستگیهای سراسری سیستم خود را مانند TypeScript، پس از نصب CLI جدید، به نحو زیر به روز کنید:
npm update -g
برای بهروز رسانی به نسخه 7 (core framework و CLI)، دستورات زیر را اجرا کنید:
ng update @angular/cli ng update @angular/core ng update rxjs
و اگر از Angular Material نیز استفاده میکنید، نیاز به اجرای دستور زیر را نیز خواهید داشت:
ng update @angular/material
و یا به صورت خلاصه دستور زیر تمام مراحل فوق را به صورت یکجا انجام میدهد:
ng update --all --force
اگر شما از Service worker مربوط به Angular استفاده میکنید، بجای versionedFiles از files استفاده کنید. رفتار همان است و تغییر نکردهاست.
6- به روز رسانی وابستگیهای ثالث پروژه
برای به روز رسانی سایر وابستگیهای پروژه، میتوان از بستهی npm-check-updates استفاده کرد:
npm install npm-check-updates -g ncu -u npm install
نظرات مطالب
Asp.Net Identity #2
همراه با Identity 2 با استفاده از روش code first چند جدول اضافه کردم و بین اونا رو ارتباط دادم . ولی متاسفانه پیغام زیر رو دریافت میکنم
ولی زمانی که ارتباط رو با جداول Identity حذف میکنم دیگه مشکلی نیست .
MyProject.Models.IdentityUserRole: : EntityType 'IdentityUserRole' has no key defined. Define the key for this EntityType. MyProject.Models.IdentityUserLogin: : EntityType 'IdentityUserLogin' has no key defined. Define the key for this EntityType. IdentityUserRoles: EntityType: EntitySet 'IdentityUserRoles' is based on type 'IdentityUserRole' that has no keys defined. IdentityUserLogins: EntityType: EntitySet 'IdentityUserLogins' is based on type 'IdentityUserLogin' that has no keys defined.
در برنامههای ASP.NET Core، امکان دریافت تنظیمات برنامه از منابع مختلفی مانند فایلهای JSON وجود دارد که در نگارشهای اخیر آن، امکان اعتبارسنجی اطلاعات آنها به صورت توکار نیز اضافه شدهاست؛ مانند:
اما این امکان در مقایسه با امکاناتی که FluentValidation در اختیار ما قرار میدهد، بسیار ابتدایی به نظر میرسد. به همین جهت در این قسمت قصد داریم امکانات اعتبارسنجی کتابخانهی FluentValidation را در حین آغاز برنامه، جهت تعیین اعتبار اطلاعات فایل کانفیگ آن، مورد استفاده قرار دهیم.
معرفی تنظیمات برنامه
فرض کنید فایل appsettings.json برنامه یک چنین محتوایی را دارد:
ایجاد مدلهای معادل تنظیمات JSON برنامه
بر اساس تعاریف JSON فوق، میتوان به مدلهای زیر رسید:
که نحوهی معرفی آن به سیستم تزریق وابستگیهای برنامه به صورت زیر است:
و پس از آن در هر قسمتی از برنامه با تزریق <IOptions<ApiSettings میتوان به اطلاعات تنظیمات برنامه دسترسی یافت.
تعریف شرطهای اعتبارسنجی مدلهای تنظیمات برنامه
پس از مدلسازی تنظیمات برنامه و همچنین اتصال آن به <IOptions<ApiSettings، اکنون میخواهیم این مدلها، شرایط زیر را برآورده کنند:
- باید مدخل ApiSettings در فایل تنظیمات برنامه وجود خارجی داشته باشد.
- میخواهیم AllowedEndpointها نامدار بوده و هر نام نیز منحصربفرد باشد.
- مقادیر timeoutها باید بین 1 و 90 تعریف شده باشند.
- تمام URLها باید منحصربفرد باشند.
- تمام URLها باید HTTPS باشند.
برای این منظور میتوان تنظیمات زیر را توسط Fluent Validation تعریف کرد:
که در اینجا نکات زیر قابل ملاحظه هستند:
- چگونه میتوان از تعریف و وجود یک مدخل فایل JSON، اطمینان حاصل کرد (اعمال RuleFor به کل مدل).
- چگونه میتوان اگر مدخلی تعریف شده بود، آنگاه برای آن اعتبارسنجی خاصی را تعریف کرد (متد When).
- چگونه میتوان شرایط سفارشی خاصی را مانند بررسی منحصربفرد بودنها، بررسی کرد (متد Must).
یکپارچه کردن اعتبارسنجی کتابخانهی FluentValidation با اعتبارسنجی توکار مدلهای تنظیمات برنامه توسط ASP.NET Core
در ابتدای بحث، امکان تعریف متد Validate را که از نگارش ASP.NET Core 2.2 اضافه شدهاست، مشاهده کردید:
میتوان این متد را با پیاده سازی اینترفیس توکار IValidateOptions نیز به سیستم ارائه داد:
و اگر سرویس پیاده سازی کنندهی آنرا با طول عمر Transient به سیستم اضافه کردیم، به صورت خودکار جهت اعتبارسنجی TOptions، مورد استفاده قرار خواهد گرفت. TOptions در این مثال همان ApiSettings است.
در ادامه یک نمونه پیاده سازی جنریک IValidateOptions استاندارد ASP.NET Core را مشاهده میکنید:
همانطور که در قسمت دوم این سری این نیز بررسی کردیم، یکی از روشهای اجرای اعتبارسنجیهای FluentValidation، کار با اینترفیس IValidator آن است که در اینجا به سازندهی این کلاس تزریق شدهاست. سپس در متد Validate این سرویس، با فراخوانی آن، کار اعتبارسنجی وهلهی دریافتی options صورت گرفته و اگر خطایی وجود داشته باشد، بازگشت داده میشود.
در آخر روش معرفی آن به سیستم به صورت زیر است:
به این ترتیب هرگاه در برنامه یک چنین تعریفی را داشته باشیم که از طریق IOptions، تنظیمات برنامه را دریافت میکند:
اگر در سیستم یک <IValidateOptions<ApiSettings متناظر با <IOptions<ApiSettings ثبت شده باشد (مانند تنظیمات متد ConfigureServices فوق)، هرگاه که فراخوانی apiSettings.Value صورت گیرد، قبل از هرکاری متد Validate سرویس پیاده سازی کنندهی IValidateOptions متناظر، فراخوانی شده و اگر خطای اعتبارسنجی وجود داشته باشد، به صورت یک استثناء بازگشت داده میشود؛ مانند:
کدهای کامل این سری را تا این قسمت از اینجا میتوانید دریافت کنید: FluentValidationSample-part05.zip
services.AddOptions<BearerTokensOptions>() .Bind(configuration.GetSection("BearerTokens")) .Validate(bearerTokens => { return bearerTokens.AccessTokenExpirationMinutes < bearerTokens.RefreshTokenExpirationMinutes; }, "RefreshTokenExpirationMinutes is less than AccessTokenExpirationMinutes. Obtaining new tokens using the refresh token should happen only if the access token has expired.");
معرفی تنظیمات برنامه
فرض کنید فایل appsettings.json برنامه یک چنین محتوایی را دارد:
{ "ApiSettings": { "AllowedEndpoints": [ { "Name": "Service 1", "Timeout": 30, "Url": "http://service1.site.com" }, { "Name": "Service 2", "Timeout": 10, "Url": "https://service2.site.com" } ] } }
ایجاد مدلهای معادل تنظیمات JSON برنامه
بر اساس تعاریف JSON فوق، میتوان به مدلهای زیر رسید:
using System; using System.Collections.Generic; namespace FluentValidationSample.Models { public class AllowedEndpoint { public string Name { get; set; } public int Timeout { get; set; } public Uri Url { get; set; } } public class ApiSettings { public IEnumerable<AllowedEndpoint> AllowedEndpoints { get; set; } } }
namespace FluentValidationSample.Web { public class Startup { public void ConfigureServices(IServiceCollection services) { services.Configure<ApiSettings>(Configuration.GetSection(nameof(ApiSettings)));
تعریف شرطهای اعتبارسنجی مدلهای تنظیمات برنامه
پس از مدلسازی تنظیمات برنامه و همچنین اتصال آن به <IOptions<ApiSettings، اکنون میخواهیم این مدلها، شرایط زیر را برآورده کنند:
- باید مدخل ApiSettings در فایل تنظیمات برنامه وجود خارجی داشته باشد.
- میخواهیم AllowedEndpointها نامدار بوده و هر نام نیز منحصربفرد باشد.
- مقادیر timeoutها باید بین 1 و 90 تعریف شده باشند.
- تمام URLها باید منحصربفرد باشند.
- تمام URLها باید HTTPS باشند.
برای این منظور میتوان تنظیمات زیر را توسط Fluent Validation تعریف کرد:
using System; using System.Linq; using FluentValidation; using FluentValidationSample.Models; namespace FluentValidationSample.ModelsValidations { public class ApiSettingsValidator : AbstractValidator<ApiSettings> { public ApiSettingsValidator() { RuleFor(apiSetting => apiSetting).NotNull() .WithMessage("مدخل ApiSettings تعریف نشدهاست."); RuleFor(apiSetting => apiSetting.AllowedEndpoints).NotNull().NotEmpty() .WithMessage("مدخل AllowedEndpoints تعریف نشدهاست."); When(apiSetting => apiSetting.AllowedEndpoints != null, () => { RuleFor(apiSetting => apiSetting.AllowedEndpoints) .Must(endpoints => endpoints.GroupBy(endpoint => endpoint.Name).Count() == endpoints.Count()) .WithMessage("نامهای سرویسها باید منحصربفرد باشند."); RuleFor(apiSetting => apiSetting.AllowedEndpoints) .Must(endpoints => !endpoints.Any(endpoint => endpoint.Timeout > 90 || endpoint.Timeout < 1)) .WithMessage("مقدار timeout باید بین 1 و 90 باشد"); RuleFor(apiSetting => apiSetting.AllowedEndpoints) .Must(endpoints => endpoints.GroupBy(endpoint => endpoint.Url.ToString().ToLower()).Count() == endpoints.Count()) .WithMessage("آدرسهای سرویسها باید منحصربفرد باشند."); RuleFor(apiSetting => apiSetting.AllowedEndpoints) .Must(endpoints => endpoints.All(endpoint => endpoint.Url.Scheme.Equals("https", StringComparison.CurrentCultureIgnoreCase))) .WithMessage("تمام آدرسها باید HTTPS باشند."); }); } } }
- چگونه میتوان از تعریف و وجود یک مدخل فایل JSON، اطمینان حاصل کرد (اعمال RuleFor به کل مدل).
- چگونه میتوان اگر مدخلی تعریف شده بود، آنگاه برای آن اعتبارسنجی خاصی را تعریف کرد (متد When).
- چگونه میتوان شرایط سفارشی خاصی را مانند بررسی منحصربفرد بودنها، بررسی کرد (متد Must).
یکپارچه کردن اعتبارسنجی کتابخانهی FluentValidation با اعتبارسنجی توکار مدلهای تنظیمات برنامه توسط ASP.NET Core
در ابتدای بحث، امکان تعریف متد Validate را که از نگارش ASP.NET Core 2.2 اضافه شدهاست، مشاهده کردید:
services.AddOptions<BearerTokensOptions>() .Bind(configuration.GetSection("BearerTokens")) .Validate(bearerTokens => { return bearerTokens.AccessTokenExpirationMinutes < bearerTokens.RefreshTokenExpirationMinutes; }, "RefreshTokenExpirationMinutes is less than AccessTokenExpirationMinutes. Obtaining new tokens using the refresh token should happen only if the access token has expired.");
namespace Microsoft.Extensions.Options { public interface IValidateOptions<TOptions> where TOptions : class { ValidateOptionsResult Validate(string name, TOptions options); } }
در ادامه یک نمونه پیاده سازی جنریک IValidateOptions استاندارد ASP.NET Core را مشاهده میکنید:
using System.Linq; using FluentValidation; using Microsoft.Extensions.Options; namespace FluentValidationSample.ModelsValidations { public class AppConfigValidator<TOptions> : IValidateOptions<TOptions> where TOptions : class { private readonly IValidator<TOptions> _validator; public AppConfigValidator(IValidator<TOptions> validator) { _validator = validator; } public ValidateOptionsResult Validate(string name, TOptions options) { if (options is null) { return ValidateOptionsResult.Fail("Configuration object is null."); } var validationResult = _validator.Validate(options); return validationResult.IsValid ? ValidateOptionsResult.Success : ValidateOptionsResult.Fail(validationResult.Errors.Select(error => error.ToString())); } } }
در آخر روش معرفی آن به سیستم به صورت زیر است:
namespace FluentValidationSample.Web { public class Startup { public void ConfigureServices(IServiceCollection services) { services.Configure<ApiSettings>(Configuration.GetSection(nameof(ApiSettings))); services.AddTransient<IValidateOptions<ApiSettings>, AppConfigValidator<ApiSettings>>();
namespace FluentValidationSample.Web.Controllers { public class HomeController : Controller { private readonly IUsersService _usersService; private readonly ApiSettings _apiSettings; public HomeController(IUsersService usersService, IOptions<ApiSettings> apiSettings) { _usersService = usersService; _apiSettings = apiSettings.Value; }
An unhandled exception occurred while processing the request. OptionsValidationException: تمام آدرسها باید HTTPS باشند.
کدهای کامل این سری را تا این قسمت از اینجا میتوانید دریافت کنید: FluentValidationSample-part05.zip
The full source tree with all the code, test code and everything that together constitutes the “Windows source code” is more than a half terabyte in size, in more than 4 million files. You can spend a year (seriously) just drilling down the source tree, more than a half million folders containing the code for every component making up the OS workstation and server products and all their editions, tools, and associated developement kits, and see what’s in there, read the file names and try to figure out what does what. It would take a life (or two) to read it all.