مطالب
آشنایی با NHibernate - قسمت هفتم

مدیریت بهینه‌ی سشن فکتوری

ساخت یک شیء SessionFactory بسیار پر هزینه و زمانبر است. به همین جهت لازم است که این شیء یکبار حین آغاز برنامه ایجاد شده و سپس در پایان کار برنامه تخریب شود. انجام اینکار در برنامه‌های معمولی ویندوزی (WinForms ،WPF و ...)، ساده است اما در محیط Stateless وب و برنامه‌های ASP.Net ، نیاز به راه حلی ویژه وجود خواهد داشت و تمرکز اصلی این مقاله حول مدیریت صحیح سشن فکتوری در برنامه‌های ASP.Net است.

برای پیاده سازی شیء سشن فکتوری به صورتی که یکبار در طول برنامه ایجاد شود و بارها مورد استفاده قرار گیرد باید از یکی از الگوهای معروف طراحی برنامه نویسی شیء گرا به نام Singleton Pattern استفاده کرد. پیاده سازی نمونه‌ی thread safe آن که در برنامه‌های ذاتا چند ریسمانی وب و همچنین برنامه‌های معمولی ویندوزی می‌تواند مورد استفاده قرار گیرد، در آدرس ذیل قابل مشاهده است:



از پنجمین روش ذکر شده در این مقاله جهت ایجاد یک lazy, lock-free, thread-safe singleton استفاده خواهیم کرد.

بررسی مدل برنامه

در این مدل ساده ما یک یا چند پارکینگ داریم که در هر پارکینگ یک یا چند خودرو می‌توانند پارک شوند.


یک برنامه ASP.Net را آغاز کرده و ارجاعاتی را به اسمبلی‌های زیر به آن اضافه نمائید:
FluentNHibernate.dll
NHibernate.dll
NHibernate.ByteCode.Castle.dll
NHibernate.Linq.dll
و همچنین ارجاعی به اسمبلی استاندارد System.Data.Services.dll دات نت فریم ورک سه و نیم

تصویر نهایی پروژه ما به شکل زیر خواهد بود:



پروژه ما دارای یک پوشه domain ، تعریف کننده موجودیت‌های برنامه جهت تهیه نگاشت‌های لازم از روی ‌آن‌ها است. سپس یک پوشه جدید را به نام NHSessionManager به آن جهت ایجاد یک Http module مدیریت کننده سشن‌های NHibernate در برنامه اضافه خواهیم کرد.

ساختار دومین برنامه (مطابق کلاس دیاگرام فوق):

namespace NHSample3.Domain
{
public class Car
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual string Color { get; set; }
}
}

using System.Collections.Generic;

namespace NHSample3.Domain
{
public class Parking
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual string Location { get; set; }
public virtual IList<Car> Cars { get; set; }

public Parking()
{
Cars = new List<Car>();
}
}
}
مدیریت سشن فکتوری در برنامه‌های وب

در این قسمت قصد داریم Http Module ایی را جهت مدیریت سشن‌های NHibernate ایجاد نمائیم.

در ابتدا کلاس Config را در پوشه مدیریت سشن NHibernate با محتویات زیر ایجاد کنید:

using FluentNHibernate.Automapping;
using FluentNHibernate.Cfg;
using FluentNHibernate.Cfg.Db;
using NHibernate.Tool.hbm2ddl;

namespace NHSessionManager
{
public class Config
{
public static FluentConfiguration GetConfig()
{
return
Fluently.Configure()
.Database(
MsSqlConfiguration
.MsSql2008
.ConnectionString(x => x.FromConnectionStringWithKey("DbConnectionString"))
)
.ExposeConfiguration(
x => x.SetProperty("current_session_context_class", "managed_web")
)
.Mappings(
m => m.AutoMappings.Add(
new AutoPersistenceModel()
.Where(x => x.Namespace.EndsWith("Domain"))
.AddEntityAssembly(typeof(NHSample3.Domain.Car).Assembly))
);
}

public static void CreateDb()
{
bool script = false;//آیا خروجی در کنسول هم نمایش داده شود
bool export = true;//آیا بر روی دیتابیس هم اجرا شود
bool dropTables = false;//آیا جداول موجود دراپ شوند
new SchemaExport(GetConfig().BuildConfiguration()).Execute(script, export, dropTables);
}
}
}
با این کلاس در قسمت‌های قبل آشنا شده‌اید. در این کلاس با کمک امکانات Auto mapping موجود در Fluent Nhibernate (مطلب قسمت قبلی این سری آموزشی) اقدام به تهیه نگاشت‌های خودکار از کلاس‌های قرار گرفته در پوشه دومین خود خواهیم کرد (فضای نام این پوشه به دومین ختم می‌شود که در متد GetConfig مشخص است).
دو نکته جدید در متد GetConfig وجود دارد:
الف) استفاده از متد FromConnectionStringWithKey ، بجای تعریف مستقیم کانکشن استرینگ در متد مذکور که روشی است توصیه شده. به این صورت فایل وب کانفیگ ما باید دارای تعریف کلید مشخص شده در متد GetConfig به نام DbConnectionString باشد:

<connectionStrings>
<!--NHSessionManager-->
<add name="DbConnectionString"
connectionString="Data Source=(local);Initial Catalog=HelloNHibernate;Integrated Security = true" />
</connectionStrings>
ب) قسمت ExposeConfiguration آن نیز جدید است.
در اینجا به AutoMapper خواهیم گفت که قصد داریم از امکانات مدیریت سشن مخصوص وب فریم ورک NHibernate استفاده کنیم. فریم ورک NHibernate دارای کلاسی است به نام NHibernate.Context.ManagedWebSessionContext که جهت مدیریت سشن‌های خود در پروژه‌های وب ASP.Net پیش بینی کرده است و از این متد در Http module ایی که ایجاد خواهیم کرد جهت ردگیری سشن جاری آن کمک خواهیم گرفت.

اگر متد CreateDb را فراخوانی کنیم، جداول نگاشت شده به کلاس‌های پوشه دومین برنامه، به صورت خودکار ایجاد خواهند شد که دیتابیس دیاگرام آن به صورت زیر می‌باشد:



سپس کلاس SingletonCore را جهت تهیه تنها و تنها یک وهله از شیء سشن فکتوری در کل برنامه ایجاد خواهیم کرد (همانطور که عنوان شده، ایده پیاده سازی این کلاس thread safe ، از مقاله معرفی شده در ابتدای بحث گرفته شده است):

using NHibernate;

namespace NHSessionManager
{
/// <summary>
/// lazy, lock-free, thread-safe singleton
/// </summary>
public class SingletonCore
{
private readonly ISessionFactory _sessionFactory;

SingletonCore()
{
_sessionFactory = Config.GetConfig().BuildSessionFactory();
}

public static SingletonCore Instance
{
get
{
return Nested.instance;
}
}

public static ISession GetCurrentSession()
{
return Instance._sessionFactory.GetCurrentSession();
}

public static ISessionFactory SessionFactory
{
get { return Instance._sessionFactory; }
}

class Nested
{
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static Nested()
{
}

internal static readonly SingletonCore instance = new SingletonCore();
}
}
}
اکنون می‌توان از این Singleton object جهت تهیه یک Http Module کمک گرفت. برای این منظور کلاس SessionModule را به برنامه اضافه کنید:

using System;
using System.Web;
using NHibernate;
using NHibernate.Context;

namespace NHSessionManager
{
public class SessionModule : IHttpModule
{
public void Dispose()
{ }

public void Init(HttpApplication context)
{
if (context == null)
throw new ArgumentNullException("context");

context.BeginRequest += Application_BeginRequest;
context.EndRequest += Application_EndRequest;
}

private void Application_BeginRequest(object sender, EventArgs e)
{
ISession session = SingletonCore.SessionFactory.OpenSession();
ManagedWebSessionContext.Bind(HttpContext.Current, session);
session.BeginTransaction();
}

private void Application_EndRequest(object sender, EventArgs e)
{
ISession session = ManagedWebSessionContext.Unbind(
HttpContext.Current, SingletonCore.SessionFactory);
if (session == null) return;

try
{
if (session.Transaction != null &&
!session.Transaction.WasCommitted &&
!session.Transaction.WasRolledBack)
{
session.Transaction.Commit();
}
else
{
session.Flush();
}
}
catch (Exception)
{
session.Transaction.Rollback();
}
finally
{
if (session != null && session.IsOpen)
{
session.Close();
session.Dispose();
}
}
}
}
}
کلاس فوق کار پیاده سازی اینترفیس IHttpModule را جهت دخالت صریح در request handling pipeline برنامه ASP.Net جاری انجام می‌دهد. در این کلاس مدیریت متدهای استاندارد Application_BeginRequest و Application_EndRequest به صورت خودکار صورت می‌گیرد.
در متد Application_BeginRequest ، در ابتدای هر درخواست یک سشن جدید ایجاد و به مدیریت سشن وب NHibernate بایند می‌شود، همچنین یک تراکنش نیز آغاز می‌گردد. سپس در پایان درخواست، این انقیاد فسخ شده و تراکنش کامل می‌شود، همچنین کار پاکسازی اشیاء نیز صورت خواهد گرفت.

با توجه به این موارد، دیگر نیازی به ذکر using جهت dispose کردن سشن جاری در کدهای ما نخواهد بود، زیرا در پایان هر درخواست اینکار به صورت خودکار صورت می‌گیرد. همچنین نیازی به ذکر تراکنش نیز نمی‌باشد، چون مدیریت آن‌را خودکار کرده‌ایم.

جهت استفاده از این Http module تهیه شده باید چند سطر زیر را به وب کانفیگ برنامه اضافه کرد:

<httpModules>
<!--NHSessionManager-->
<add name="SessionModule" type="NHSessionManager.SessionModule"/>
</httpModules>
بدیهی است اگر نخواهید از Http module استفاده کنید باید این کدها را در فایل Global.asax برنامه قرار دهید.

اکنون مثالی از نحوه‌ی استفاده از امکانات فراهم شده فوق به صورت زیر می‌تواند باشد:
ابتدا کلاس ParkingContext را جهت مدیریت مطلوب‌تر LINQ to NHibernate تشکیل می‌دهیم.

using System.Linq;
using NHibernate;
using NHibernate.Linq;
using NHSample3.Domain;

namespace NHSample3
{
public class ParkingContext : NHibernateContext
{
public ParkingContext(ISession session)
: base(session)
{ }

public IOrderedQueryable<Car> Cars
{
get { return Session.Linq<Car>(); }
}

public IOrderedQueryable<Parking> Parkings
{
get { return Session.Linq<Parking>(); }
}
}
}
سپس در فایل Default.aspx.cs برنامه ، برای نمونه تعدادی رکورد را افزوده و نتیجه را در یک گرید ویوو نمایش خواهیم داد:

using System;
using System.Collections.Generic;
using System.Linq;
using NHibernate;
using NHSample3.Domain;
using NHSessionManager;

namespace NHSample3
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
//ایجاد دیتابیس در صورت نیاز
//Config.CreateDb();

//ثبت یک سری رکورد در دیتابیس
ISession session = SingletonCore.GetCurrentSession();

Car car1 = new Car() { Name = "رنو", Color = "مشکلی" };
session.Save(car1);
Car car2 = new Car() { Name = "پژو", Color = "سفید" };
session.Save(car2);

Parking parking1 = new Parking()
{
Location = "آدرس پارکینگ مورد نظر",
Name = "پارکینگ یک",
Cars = new List<Car> { car1, car2 }
};

session.Save(parking1);

//نمایش حاصل در یک گرید ویوو
ParkingContext db = new ParkingContext(session);
var query = from x in db.Cars select new { CarName = x.Name, CarColor = x.Color };
GridView1.DataSource = query.ToList();
GridView1.DataBind();
}
}
}
مدیریت سشن فکتوری در برنامه‌های غیر وب

در برنامه‌های ویندوزی مانند WinForms ، WPF و غیره، تا زمانیکه یک فرم باز باشد، کل فرم و اشیاء مرتبط با آن به یکباره تخریب نخواهند شد، اما در یک برنامه ASP.Net جهت حفظ منابع سرور در یک محیط چند کاربره، پس از پایان نمایش یک صفحه وب، اثری از آثار اشیاء تعریف شده در کدهای آن صفحه در سرور وجود نداشته و همگی بلافاصله تخریب می‌شوند. به همین جهت بحث‌های ویژه state management در ASP.Net در اینباره مطرح است و مدیریت ویژه‌ای باید روی آن صورت گیرد که در قسمت قبل مطرح شد.
از بحث فوق، تنها استفاده از کلاس‌های Config و SingletonCore ، جهت استفاده و مدیریت بهینه‌ی سشن فکتوری در برنامه‌های ویندوزی کفایت می‌کنند.

دریافت سورس برنامه قسمت هفتم

ادامه دارد ....

اشتراک‌ها
چند نکته درباره HTML

A while ago I wrote an article with some CSS tips, now it’s time to give some polish to our HTML! In this article I’ll share some tips and advice about HTML code. Some of this guidance will be best suited for beginners – how to properly build paragraphs, use headings, or improve forms, but we will also discuss SVG sprites for icons, a somewhat more advanced topic. 

چند نکته درباره HTML
اشتراک‌ها
کتابخانه dragula

Drag and drop so simple it hurts  Demo

Framework support includes vanilla JavaScript, Angular, and React.

Features

  • Super easy to set up
  • No bloated dependencies
  • Figures out sort order on its own
  • A shadow where the item would be dropped offers visual feedback
  • Touch events!
  • Seamlessly handles clicks without any configuration 
کتابخانه dragula
اشتراک‌ها
طراحی رابط کاربری آسان با فریم ورک کوانتوم یو آی
The most powerful NATIVE AngularJS and Bootstrap CSS based UI components make developer life 
easyCompletely MVVM structure, easy, light, fast, mobile friendly 25+ components and lots of native angular services.Optimized and extended Bootstrap based CSS structure with pure CSS3 plugins. 
طراحی رابط کاربری آسان با فریم ورک کوانتوم یو آی
مطالب
تولید و ارسال خودکار بسته‌های NuGet پروژه‌های NET Core. به کمک AppVeyor
اگر پروژه‌ی شما به همراه توزیع بسته‌های نیوگت است، پس از مدتی، از build و آپلود دستی بسته‌های نیوگت آن‌ها خسته خواهید شد. همچنین این سؤال هم برای مصرف کنندگان بسته‌ی نیوگت شما همواره وجود خواهد داشت: «آیا بسته‌ی نهایی را که آپلود کرده، دقیقا بر اساس سورس کد موجود در مخزن کد عمومی آن تهیه شده‌است؟»
برای رفع این مشکلات، از روش‌های توسعه‌ی به همراه ابزارهای یکپارچگی مداوم استفاده می‌شود. برای نمونه، AppVeyor یکی از سرویس‌های ابری یکپارچگی مداوم (Continuous Integration و یا به اختصار CI) است. به کمک آن می‌توان یک image از ویندوز سرور را به همراه ابزارهای build، آزمایش و توزیع برنامه‌های NET. در اختیار داشت. این سرویس، مخزن کد شما را مونیتور کرده و هر زمانیکه تغییری را در آن ایجاد کردید، آن‌ها را به صورت خودکار build و در صورت موفقیت آمیز بودن این عملیات، بسته‌ی نیوگت متناظری را به سایت nuget.org ارسال می‌کند. بنابراین پس از یکپارچه کردن مخزن کد خود با این نوع سرویس‌های یکپارچگی مداوم، دیگر حتی نیازی به build دستی آن نیز نخواهید داشت. همینقدر که کدی را به مخزن کد تحت نظر، commit کنید، مابقی مراحل آن خودکار است.
به همین جهت در این مطلب قصد داریم نحوه‌ی اتصال یک مخزن کد GitHub را به سرویس یکپارچگی مداوم AppVeyor، جهت تولید خودکار بسته‌های Nuget، بررسی کنیم.




معرفی سرویس ابری AppVeyor

AppVeyor یک راه حل یکپارچگی مداوم چند سکویی است که استفاده‌ی از آن برای پروژه‌های سورس باز رایگان است و سازگاری فوق العاده‌ای را با محصولات مایکروسافت دارد. برای ورود به آن می‌توان از اکانت‌های GitHub ،BitBucket و VSTS (Visual Studio Team Services) استفاده کرد.
گردش کاری متداول یکپارچگی مداوم AppVeyor به این صورت است:
الف) با اکانت GitHub خود به آن وارد شوید.
ب) یک مخزن کد GitHub خود را به آن Import کنید.
ج) به مخزن کد GitHub خود یک فایل yml. تنظیمات مخصوص AppVeyor را اضافه کنید.
د) نظاره‌گر Build و توزیع خودکار پروژه‌ی خود باشید.


ایجاد اکانت و اتصال به مخزن کد GitHub

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


پس از ورود موفق، گزینه‌ی new project را انتخاب کنید:


در ادامه مخزن کد GitHub و نوع عمومی آن‌را انتخاب می‌کنیم تا AppVeyor بتواند پروژه‌های آن‌را Import کند و همچنین به آن‌ها web hookهایی را اضافه کند تا با اعمال تغییراتی در سمت GitHub، کار اطلاع رسانی آن‌ها به AppVeyor به صورت خودکار صورت گیرد:


پس از آن لیست مخزن‌های کد شما در همینجا ارائه می‌شود تا بتوانید یک یا چند مورد را انتخاب کنید:


انجام تنظیمات عمومی مخزن کد

در صفحه‌ی بعدی، برگه‌ی settings و سپس از منوی کنار صفحه‌ی آن، گزینه‌ی ‌General را انتخاب کنید:


در اینجا اگر پروژه‌ی شما از نوع NET Core. است، گزینه‌ی NET Core .csproj patching. را انتخاب نمائید:


سپس در پایین صفحه بر روی دکمه‌ی Save کلیک کنید.


انتخاب و تنظیم محیط Build

در ادامه در برگه‌ی settings و سپس از منوی کنار صفحه‌ی آن، گزینه‌ی Environment را انتخاب کنید:


در این صفحه، worker image را بر روی VS 2017 قرار دهید و همچنین در قسمت Cached directories and files، مسیر C:\Users\appveyor\.dnx را جهت کش کردن عملیات Build و بالا بردن سرعت آن، مقدار دهی کنید. سپس در پایین صفحه بر روی دکمه‌ی Save کلیک نمائید.

اکنون بر روی گزینه‌ی Build در منوی سمت چپ صفحه کلیک کنید. در اینجا سه حالت msbuild ،script و off را می‌توان انتخاب کرد.
- در حالت msbuild، که ساده‌ترین حالت ممکن است، فایل sln. مخزن کد، یافت شده و بر اساس آن به صورت خودکار تمام پروژه‌های این solution یکی پس از دیگری build خواهند شد. این مورد برای برنامه‌های Full .NET Framework شاید گزینه‌ی مناسبی باشد.
- حالت script برای پروژه‌های NET Core. مناسب‌تر است و در این حالت می‌توان کنترل بیشتری را بر روی build داشت. به علاوه این روش بر روی لینوکس هم کار می‌کند؛ زیرا در آنجا دسترسی به msbuild نداریم.
- حالت off به معنای خاموش کردن عملیات build است.

در اینجا گزینه‌ی cmd را جهت ورود build script انتخاب می‌کنیم:


سپس دستورات ذیل را جهت ورود به پوشه‌ی پروژه‌ی کتابخانه (جائیکه فایل csproj آن قرار دارد)، بازیابی وابستگی‌های پروژه و سپس تولید بسته‌ی نیوگتی از آن، وارد می‌کنیم:
cd ./src/DNTPersianUtils.Core
dotnet restore
dotnet pack -c release
cd ../..
در ادامه در پایین صفحه بر روی دکمه‌ی Save کلیک نمائید.
ذکر  ../.. cd  در انتهای این دستورات ضروری است. در غیر اینصورت cd بعدی در تنظیماتی دیگر، داخل همین پوشه انجام می‌شود.


تنظیم اجرای خودکار آزمون‌های واحد


در همین صفحه، گزینه‌های settings -> tests -> script -> cmd را انتخاب و سپس دستورات زیر را وارد کرده و آن‌را ذخیره کنید:
cd ./src/DNTPersianUtils.Core.Tests
dotnet restore
dotnet test
cd ../..
به این ترتیب به صورت خودکار آزمون‌های واحد موجود در پروژه‌ی انتخابی، توسط NET Core CLI. اجرا خواهند شد.


تنظیم اطلاع رسانی خودکار از اجرای عملیات


در برگه‌ی settings -> notifications مطابق تنظیمات فوق می‌توان نوع email را جهت اطلاع رسانی شکست انجام عملیات یکپارچگی مداوم، انتخاب کرد.


آزمایش Build خودکار

برای آزمایش تنظیماتی که انجام دادیم، به برگه‌ی latest build مراجعه کرده و بر روی دکمه‌ی new build کلیک کنید تا اسکریپت‌های build و test فوق اجرا شوند. بدیهی است اجرای بعدی این اسکریپت‌ها خودکار بوده و به ازای هر commit به GitHub، بدون نیاز به مراجعه‌ی مستقیم به appveyor صورت می‌گیرند.



اضافه کردن نماد AppVeyor به پروژه

در تنظیمات برگه‌ی Settings، گزینه‌ی AppVeyor badge نیز در منوی سمت چپ صفحه، وجود دارد:


در اینجا همان کدهای mark down آن‌را انتخاب کرده و به ابتدای فایل readme پروژه‌ی خود اضافه کنید. برای نمونه نماد فعلی (تصویر فوق)، build failing را نمایش می‌دهد؛ چون سه آزمون واحد آن مشکل دارند و باید اصلاح شوند.
پس از رفع مشکلات پروژه و commit آن‌ها، build و اجرای خودکار آزمون‌های واحد آن توسط AppVeyor صورت گرفته و اینبار این نماد به صورت زیر تغییر می‌کند:



ارسال خودکار بسته‌ی نیوگت تولید شده به سایت nuget.org

برای ارسال خودکار حاصل Build، به سایت نیوگت، نیاز است یک API Key داشته باشیم. به همین جهت به صفحه‌ی مخصوص آن در سایت nuget پس از ورود به سایت آن، مراجعه کرده و یک کلید API جدید را صرفا برای این پروژه تولید کنید (در قسمت Available Packages بسته‌ی پیشینی را که دستی آپلود کرده بودید انتخاب کنید).
پس از کپی کردن کلید تولید شده‌ی در سایت nuget، به قسمت settings -> deployment مراجعه کرده و یک تامین کننده‌ی جدید از نوع nuget را اضافه کنید:


در اینجا API Key را ذکر خواهیم کرد. سپس در پایین صفحه بر روی دکمه‌ی Save کلیک کنید.

همچنین نیاز است مشخص کنیم که بسته‌های nupkg تولید شده در چه مسیری قرار دارند. به همین جهت در قسمت settings -> artifacts مسیر پوشه‌ی bin نهایی را ذکر می‌کنیم:


این مورد را نیز با کلیک بر روی دکمه‌ی Save ذخیره کنید.

اکنون اگر نگارش جدیدی را به GitHub ارسال کنیم (تغییر VersionPrefix در فایل csproj و سپس commit آن)، پس از Build پروژه، بسته‌ی نیوگت آن نیز به صورت خودکار تولید شده و به سایت nuget.org ارسال می‌شود. لاگ آن‌را در پایین صفحه‌ی برگه‌ی latest build می‌توانید مشاهده کنید.



ساده سازی مراحل تنظیمات AppVeyor

در صفحه‌ی settings‌، در منوی سمت چپ آن، گزینه‌ی export YAML نیز وجود دارد. در اینجا می‌توان تمام تنظیمات انجام شده‌ی فوق را با فرمت yml. دریافت کرد و سپس این فایل را به ریشه‌ی مخزن کد خود افزود. با وجود این فایل، دیگر نیازی به طی کردن دستی هیچکدام از مراحل فوق نیست.
برای نمونه فایل appveyor.yml نهایی مطابق با توضیحات این مطلب، چنین محتوایی را دارد:
version: 1.0.{build}
image: Visual Studio 2017
dotnet_csproj:
  patch: true
  file: '**\*.csproj'
  version: '{version}'
  package_version: '{version}'
  assembly_version: '{version}'
  file_version: '{version}'
  informational_version: '{version}'
cache: C:\Users\appveyor\.dnx
build_script:
- cmd: >-
    cd ./src/DNTPersianUtils.Core

    dotnet restore

    dotnet pack -c release

    cd ../..
test_script:
- cmd: >-
    cd ./src/DNTPersianUtils.Core.Tests

    dotnet restore

    dotnet test

    cd ../..
artifacts:
- path: ./src/DNTPersianUtils.Core/bin/release/*.nupkg
  name: NuGet
deploy:
- provider: NuGet
  api_key:
    secure: xyz
  skip_symbols: true
notifications:
- provider: Email
  to:
  - me@yahoo.com
  on_build_success: false
  on_build_failure: true
  on_build_status_changed: true
بنابراین بجای طی مراحل عنوان شده‌ی در این بحث می‌توانید یک فایل appveyor.yml را با محتوای فوق (پس از اصلاح مسیرها و نام‌ها) در ریشه‌ی پروژه‌ی خود قرار دهید و ... صرفا مخزن کد آن‌را در appveyor ثبت و import کنید. مابقی مراحل یکپارچگی مداوم آن خودکار است و نیاز به تنظیم دیگری ندارد. فقط برای آزمایش آن به برگه‌ی Latest build مراجعه کرده و یک build جدید را شروع کنید تا مطمئن شوید همه چیز به درستی کار می‌کند.
یک نکته: api_key ذکر شده‌ی در اینجا در قسمت secure، رمزنگاری شده‌است. برای تولید آن می‌توانید از مسیر https://ci.appveyor.com/tools/encrypt استفاده کنید. به این صورت مشکلی با عمومی کردن فایل appveyor.yml خود در GitHub نخواهید داشت.
نظرات مطالب
افزودن و اعتبارسنجی خودکار Anti-Forgery Tokens در برنامه‌های Angular مبتنی بر ASP.NET Core
سلام
من از ASP. Net Web API 2  برای سرویس هام استفاده می‌کنم، برای سمت Front از Angular 6
چطور میتونم Anti-Forgery Token رو توش پیاده سازی کنم، متاسفانه مطلب مفیدی پیدا نکردم که کمک کنه. (نمونه همین مورد رو با AngularJS پیاده کردم، ولی ظاهرا اینجا یه کم متفاوت هست)
ممنون میشم راهنمایی کنید
اشتراک‌ها
Angular 1.x: The plan forward - یادداشت های جلسات AngularJs

Angular 1.3 might be the best Angular yet, but there's still lots of high impact work to be done on the 1.x branch. We still have Material Design, our new router, and improved internationalization of Angular apps still to come ... 

The Angular 1.x project needs someone to be fully committed to keeping v1 moving forward, and supporting the Angular ecosystem that has grown around it.

That's why I'm delighted that Pete Bacon Darwin has agreed to take over the leadership role for Angular v1.  

But Pete can't do this alone. He needs Brian, Caitlin, and Chirayu to help make v1 even more awesome. Jeff will help out with google3 sync and releases, and familiar faces like Matias Niemela and Pawel Kozlowski (who co-wrote one of the first books on Angular with Pete) will be ongoing contributors. We're also looking forward to meeting new faces. Over time, some of these folks will shift their focus towards Angular 2, but for the immediate future, what's most important is that Angular 1.x is and continues to be well taken care of.  

Angular 1.x: The plan forward - یادداشت های جلسات AngularJs
مطالب
مفهوم Workspace در Angular
Workspace، اولین بار در انگیولار 6 معرفی شد. Angular Workspace به شما اجازه می‌دهد کل web application خود را به چندین پروژه‌ی کوچکتر سازماندهی کنید. بیشتر پروژه‌های کوچک انگیولار تنها شامل یک یا دو پروژه، به ازای هر Workspace می‌باشند. برای مثال وقتی شما یک پروژه‌ی جدید انگیولار را با Angular CLI ایجاد می‌کنید، در این حالت Workspace شامل یک app  واقعی و یک پروژه e2e tests می‌باشد. 

مستندات انگیولار یک پروژه را به صورت زیر توصیف می‌کند: 
A set of files that comprise a standalone app, a library, or a set of end-to-end (e2e) tests.


درست همانند مفهوم یک کتابخانه در توسعه نرم افزار، یک کتابخانه اشاره دارد به مجموعه‌ای از کد‌های با قابلیت استفاده‌ی مجدد که می‌توانند بین پروژه‌های مختلف به اشتراک گذاشته شوند؛ هم چنین Angular CLI این کار را برای شما آسان می‌کند تا کتابخانه خودتان را در یک مرکز ثبت مثل npm  انتشار دهید تا توسط دیگر توسعه دهندگان استفاده شود.
نوع Application اشاره به یک Application مستقل انگیولار دارد.    


Create Empty Workspaces  

در انگیولار 7 یک CLI option جدید ( create-application-- ) معرفی شد که شما می‌توانید با اضافه کردن این option به دستور ng new، سبب ایجاد یک Workspace خالی شوید. این option  با دستور ng new استفاده می‌شود و می‌تواند مقدار true یا false را دریافت کند که به صورت پیش فرض به true  تنظیم شده است. بنابراین وقتی شما یک پروژه‌ی جدید را ایجاد می‌کنید، سبب ایجاد یک پروژه‌ی اولیه انگیولار در Workspace هستید؛ همچنین می‌توانید create-application-- را به false تنظیم کنید تا CLI یک پروژه اولیه انگیولار را در Workspace  ایجاد نکند .

اکنون اجازه دهید آن را در عمل ببینیم: 
مطمئن شوید که نگارش انگیولار شما، 7 یا بالاتر باشد:
ng --version

Command Prompt را باز کرده و سپس درستور زیر را در آن اجرا کنید:
ng new angular-apps --create-application=false
سپس Angular CLI این هشدار را به شما می‌دهد که آیا تمایل دارید، Angular routing را اضافه کنید و همچنین از کدام stylesheet format تمایل دارید که استفاده کنید؛ سپس فایل‌های زیر تولید خواهند شد:  
angular-apps/README.md
angular-apps/angular.json
angular-apps/package.json
angular-apps/tsconfig.json
angular-apps/tslint.json
angular-apps/.editorconfig
angular-apps/.gitignore
و همچنین CLI تمام وابستگی‌های انگیولار را در یک پوشه به نام node_modules نصب خواهد کرد.


اکنون به Command Prompt برگردیم و وارد Angular Workspace خودمان شویم:
cd angular-apps

در ادامه یک پروژه جدید را با دستور زیر ایجاد می‌کنیم:
ng generate application admin
دستور بالا سبب ایجاد دو پروژه می‌شود ( admin  و admin-e2e )، در پوشه Projects. 
 همچنین می‌توانید یک کتابخانه را در Workspace خود با استفاده از دستور زیر ایجاد کنید:
ng generate library ngx-qrcode
ngx-qrcode نام کتابخانه می‌باشد. این کتابخانه در پوشه projects، درست مثل مابقی Application ها اضافه خواهد شد. 
بعد از ایجاد کردن چندین Application بدون Application پیش فرض برای Workspace خود، می‌توانید اقدام به ایجاد modules ، service ، components  و ... در یک پروژه مشخص با استفاده از project option-- کنید. 

برای نمونه یک سرویس را در پروژه admin ایجاد می‌کنیم:
ng generate service auth --project=admin
که سبب ایجاد دو فایل زیر می‌شود:
projects/admin/src/app/auth.service.spec.ts
projects/admin/src/app/auth.service.ts

Serving Specific Apps in Your Workspace 

جهت به خدمت گرفتن یک Application مشخص در Workspace دستور زیر را اجرا کنید:
ng serve admin
admin نام Application شما می‌باشد که می‌خواهید آن را به خدمت بگیرید. 


نکته
اگر در Command Prompt دستور زیر را وارد کنید: 
ng new
سریعا هشدار زیر را به شما می‌دهد:
What name would you like to use for the new workspace and initial project?
از شما می‌خواهد که نام Workspace  مورد نظرتان را وارد کنید و بعد از آن همان دو هشدار Routing و stylesheet format  می‌باشد که سبب ایجاد یک پروژه اولیه انگیولار در Workspace می‌شود.


نتیجه گیری 
در این مطلب متوجه مفهوم Angular Workspace و روش ایجاد کردن یک Workspace خالی شدیم و همچنین چگونه یک Application و یک Library را در یک Workspace   ایجاد کنیم.