معرفی پروژه Orchard
برای پروژه Orchad سه هدف تعیین شده است :
در حال حاضر Orchard بیشتر به عنوان یک سکو (platform) برای ساخت وب سایتهای ایجاد محتوی استفاده میشود آنچه در Orchard حائز اهمیت است ذکر این نکته است که این سیستم به طور کامل با استفاده از ابزارهای متن باز نوشته شده است. Orchard از ASP.NET MVC 3.0 به همراه View engine جدید و فوق العاده آن یعنی Razor بهره میبرد. همچنین این پروژه وابستگی زیادی به دیگر ابزارهای متن باز نظیر NHibernate برای دسترسی به دادهها و همچنین Autofac برای dependency injection دارد شایان ذکر است که مجوز استفاده از Orchard تحت لیسانس BSD است.
طبق اعلام وب سایت رسمی این پروژه در عرض حدود یک سالی که از ارائه این CMS میگذرد بیش از یک میلیون بار دانلود و بیش از 300 ماژول و تم برای آن ساخته شده است که در گالری آن در دسترس میباشد. Orchard به صورت ریلیزهای جزئی ارائه میشود و جدیدترن نسخه آن در هنگام نوشتن این متن 1.5.1 میباشد.
تعداد زیادی سیستمهای مدیریت محتوای تجاری و یا متن باز در طول این سالها با استفاده از دات نت ارائه شده اند. (DotNetNuke (DNN بدون تردید یک از معروفترین و قدرتمندترین آنها است. این CMS در ابتدا با VB.NET نوشته شد و این رویه تا مدتها ادامه داشت تا اینکه در نسخه اخیر به #C تغییر کرد. اگرچه DNN و همچنین پروژه متن باز دیگری به نام Umbraco هر دو محبوب هستند اما با استفاده از WebFormها پیاده سازی شده اند( البته Umbraco در نسخه 5 قصد داشت که از ASP.NET MVC استفاده کند اما علی رغم در دسترس قرار گرفتن این نسخه ظاهرا تیم Umbraco برای تمرکز بیشتر روی نسخه وب فرمی, تصمیم ندارند این پروژه را ادامه دهند.) امروزه وب فرمها همانند گذشته محبوب نیستند به همین دلیل رغبت کمتری برای استفاده از این CMSها نسبت به قبل وجود دارد. با توجه به شواهد موجود بسیاری از برنامه نویسان دات نتی به سمت ASP.NET MVC مهاجرت کرده اند به همین دلیل سیستم Orchard بر مبنای این تکنولوژی نسبتا جدید دات نت پیاده شده است. با استفاده از Orchard میتوان یک وب سایت با عملکرد بسیار بالا بدون نوشتن حتی یک خط کد ایجاد نمود. اما مانند هر سیستم مدیریت محتوی دیگری اگر بخواهیم به آن قابلیت هایی را اضافه کنیم که به صورت پیش فرض در آن نیست باید با ساختار آن به خوبی آشنا شویم و همچنین بر ابزارهای مورد نیاز این کار نیز احاطه داشته باشیم. برای دریافت اطلاعات بیشتر میتوانید به وب سایت رسمی این پروژه در اینجا مراجعه کنید
تاکنون تیم Xamarian مجوز استفاده از بسیاری از کتابخانههای جدید دات نت را که لیست آنها را در لینک اصلی مطلب جاری میتوانید پیدا کنید، نداشتند که این مشکل الان برطرف شده.
نظر شخصی بنده اینست که کلاسهای پیاده سازی شده برای رمزنگاری و رمزگشایی به شدت نگاه امنیتی بالایی را تدارک دیده است که در بیشتر سناریوها واقعا نیازی به اینهمه سطح از پیچیدگی وجود ندارد. در واقع میتوان با پیاده سازی واسط IDataProtectionProvider و تزریق آن به سیستم از روش رمزنگاری و رمزگشایی دلخواهی استفاده کرد.
آشنایی با TransactionScope
ASP.NET MVC #22
گذشته از این موضوع؛ کلاً جدا کردن Resource ها در یک Assembly دیگر بهتر است یا در پروژه UI؟ البته مطمئناً کمترین حسن آن استفاده مجدد Resourceها در پروژههایی است که پلتفرمهای مختلف دارند مثل Win و Web یا حتی Mobile. به طور عملی در پروژهای این جداسازی Resource را انجام ندادم. شما تجربه این کار را در پروژههای بزرگ داشتید؟
در قسمت بعد، قالب را هم از نوع empty انتخاب مینماییم.
در ادامه فایل project.json را باز کرده و در قسمت dependencies، تغییرات زیر را اعمال نمایید.
قبل از اینکه شما را از این همه وابستگی نگران کنم، باید عرض کنم فقط Microsoft.Owin , Microsoft.AspNetCore.Owin، پکیجهای اجباری هستند؛ باقی آنها برای نشان دادن انعطاف پذیری بالای این روش میباشند:
"dependencies": { "Microsoft.AspNet.OData": "5.9.1", "Microsoft.AspNet.SignalR": "2.2.1", "Microsoft.AspNet.WebApi.Client": "5.2.3", "Microsoft.AspNet.WebApi.Core": "5.2.3", "Microsoft.AspNet.WebApi.Owin": "5.2.3", "Microsoft.AspNetCore.Diagnostics": "1.0.0", "Microsoft.AspNetCore.Hosting": "1.0.0", "Microsoft.AspNetCore.Mvc": "1.0.0", "Microsoft.AspNetCore.Owin": "1.0.0", "Microsoft.AspNetCore.Server.IISIntegration": "1.0.0", "Microsoft.AspNetCore.Server.Kestrel": "1.0.0", "Microsoft.Extensions.Logging.Console": "1.0.0", "Microsoft.Net.Http": "2.2.29", "Microsoft.Owin": "3.0.1", "Microsoft.Owin.Diagnostics": "3.0.1", "Microsoft.Owin.FileSystems": "3.0.1", "Microsoft.Owin.StaticFiles": "3.0.1", "Newtonsoft.Json": "9.0.1" }, //etc...
بعد از ذخیره کردن این فایل، در پنجرهی Output خود شاهد دانلود شدن این پکیجها خواهید بود. در اینجا پکیجهای مربوط به Owin, Odata, SignalR را مشاهد میکنید. ضمن اینکه در کنار آن، AspNetCore.Mvc را نیز مشاهده میفرمایید. دلیل این کار این است که این دو نوع متفاوت قرار است در کنار هم کار کنند و هیچ مشکلی با دیگری ندارند.
در مسیر اصلی پروژهی خود کلاسی به نام OwinExtensions را با محتوای زیر بسازید:
namespace OwinCore { public static class OwinExtensions { public static IApplicationBuilder UseOwinApp( this IApplicationBuilder aspNetCoreApp, Action<IAppBuilder> configuration) { return aspNetCoreApp.UseOwin(setup => setup(next => { AppBuilder owinAppBuilder = new AppBuilder(); IApplicationLifetime aspNetCoreLifetime = (IApplicationLifetime)aspNetCoreApp.ApplicationServices.GetService(typeof(IApplicationLifetime)); AppProperties owinAppProperties = new AppProperties(owinAppBuilder.Properties); owinAppProperties.OnAppDisposing = aspNetCoreLifetime?.ApplicationStopping ?? CancellationToken.None; owinAppProperties.DefaultApp = next; configuration(owinAppBuilder); return owinAppBuilder.Build<Func<IDictionary<string, object>, Task>>(); })); } } }
یک Extension Method به نام UseOwinApp اضافه شده به IApplicationBuilder که مربوط به ASP.NET Core میباشد و درون آن نیز AppBuilder را که مربوط به Owin pipeline میباشد، نمونه سازی کردهایم که باعث میشود Owin pipeline بر روی ASP.NET Core pipeline سوار شود.
حال میخواهیم یک Middleware سفارشی را با استفاده از Owin نوشته و در Startup پروژه، آن را فراخوانی نماییم. کلاسی به نام AddSampleHeaderToResponseHeadersOwinMiddleware را با محتوای زیر تولید مینماییم:
namespace OwinCore { public class AddSampleHeaderToResponseHeadersOwinMiddleware : OwinMiddleware { public AddSampleHeaderToResponseHeadersOwinMiddleware(OwinMiddleware next) : base(next) { } public async override Task Invoke(IOwinContext context) { //throw new InvalidOperationException("ErrorTest"); context.Response.Headers.Add("Test", new[] { context.Request.Uri.ToString() }); await Next.Invoke(context); } } }
کلاسی است که از owinMiddleware ارث بری کرده و در متد override شدهی Invoke نیز با استفاده از IOwinContext، به پیاده سازی Middleware خود میپردازیم. Exception مربوطه را comment کرده (بعدا در مرحلهی تست از آن نیز استفاده مینماییم) و در خط بعدی در هدر response هر request، یک شیء را به نام Test و با مقدار Uri آن request، میسازیم.
خط بعدی هم اعلام میدارد که به Middleware بعدی برود.
در ادامه فایل Startup.cs را باز کرده و اینگونه متد Configure را تغییر دهید:
public void Configure(IApplicationBuilder aspNetCoreApp, IHostingEnvironment env) { aspNetCoreApp.UseOwinApp(owinApp => { if (env.IsDevelopment()) { owinApp.UseErrorPage(new ErrorPageOptions() { ShowCookies = true, ShowEnvironment = true, ShowExceptionDetails = true, ShowHeaders = true, ShowQuery = true, ShowSourceCode = true }); } owinApp.Use<AddSampleHeaderToResponseHeadersOwinMiddleware>(); }); }
مشاهده میفرمایید با استفاده از UserOwinApp میتوانیم Middlewareهای Owinی خود را register نماییم و نکتهی قابل توجه این است که در کنار آن نیز میتوانیم از IHostingEnviroment مربوط به ASP.NET core استفاده نماییم. owinApp.UseErrorPage از Microsoft.Owin.Diagnostics گرفته شده است و در خط بعدی نیز Middleware شخصی خود را register کردهایم. پروژه را run کرده و در response این را مشاهد مینمایید.
اکنون اگر در Middleware سفارشی خود، آن Exception را از حالت comment در بیاوریم، در صورتیکه در حالت development باشیم، با این صفحه مواجه خواهیم شد:
Exception مربوطه را به حالت comment گذاشته و ادامه میدهیم.
برای اینکه نشان دهیم Owin و ASP.NET Core pipeline در کنار هم میتوانند کار کنند، یک Middleware را از نوع ASP.NET Core نوشته و آن را register مینماییم. کلاسی جدیدی را به نام AddSampleHeaderToResponseHeadersAspNetCoreMiddlware با محتوای زیر میسازیم:
namespace OwinCore { public class AddSampleHeaderToResponseHeadersAspNetCoreMiddlware { private readonly RequestDelegate Next; public AddSampleHeaderToResponseHeadersAspNetCoreMiddlware(RequestDelegate next) { Next = next; } public async Task Invoke(HttpContext context) { //throw new InvalidOperationException("ErrorTest"); context.Response.Headers.Add("Test2", new[] { "some text" }); await Next.Invoke(context); } } }
متد Configure در Startup.cs را نیز اینگونه تغییر میدهیم
public void Configure(IApplicationBuilder aspNetCoreApp, IHostingEnvironment env) { aspNetCoreApp.UseOwinApp(owinApp => { if (env.IsDevelopment()) { owinApp.UseErrorPage(new ErrorPageOptions() { ShowCookies = true, ShowEnvironment = true, ShowExceptionDetails = true, ShowHeaders = true, ShowQuery = true, ShowSourceCode = true }); } owinApp.Use<AddSampleHeaderToResponseHeadersOwinMiddleware>(); }); aspNetCoreApp.UseMiddleware<AddSampleHeaderToResponseHeadersAspNetCoreMiddlware>(); }
اکنون AddSampleHeaderToResponseHeadersAspNetCoreMiddlware رجیستر شده است و بعد از run کردن پروژه و بررسی header response باید این را ببینیم
میبینید که به ترتیب اجرای Middlewareها، ابتدا Test مربوط به Owin و بعد آن Test2 مربوط به ASP.NET Core تولید شده است.
حال اجازه دهید Odata را با استفاده از Owin پیاده سازی نماییم. ابتدا کلاسی را به نام Product با محتوای زیر تولید نمایید:
namespace OwinCore { public class Product { public int Id { get; set; } public string Name { get; set; } public decimal Price { get; set; } } }
حال کلاسی را به نام ProductsController با محتوای زیر میسازیم:
namespace OwinCore { public class ProductsController : ODataController { [EnableQuery] public IQueryable<Product> Get() { return new List<Product> { new Product { Id = 1, Name = "Test" , Price = 10 } } .AsQueryable(); } } }
اگر مقالهی پیاده سازی Crud با استفاده از OData را مطالعه کرده باشید، قاعدتا با این کدها آشنا خواهید بود. ضمن اینکه پرواضح است که OData هیچ وابستگی به entity framework ندارد.
برای config آن نیز در Startup.cs پروژه و متد Configure، تغییرات زیر را اعمال مینماییم.
public void Configure(IApplicationBuilder aspNetCoreApp, IHostingEnvironment env) { //aspNetCoreApp.UseMvc(); aspNetCoreApp.UseOwinApp(owinApp => { if (env.IsDevelopment()) { owinApp.UseErrorPage(new ErrorPageOptions() { ShowCookies = true, ShowEnvironment = true, ShowExceptionDetails = true, ShowHeaders = true, ShowQuery = true, ShowSourceCode = true }); } // owinApp.UseFileServer(); as like as asp.net core static files middleware // owinApp.UseStaticFiles(); as like as asp.net core static files middleware // owinApp.UseWebApi(); asp.net web api / odata / web hooks HttpConfiguration webApiConfig = new HttpConfiguration(); ODataModelBuilder odataMetadataBuilder = new ODataConventionModelBuilder(); odataMetadataBuilder.EntitySet<Product>("Products"); webApiConfig.MapODataServiceRoute( routeName: "ODataRoute", routePrefix: "odata", model: odataMetadataBuilder.GetEdmModel()); owinApp.UseWebApi(webApiConfig); owinApp.MapSignalR(); //owinApp.Use<AddSampleHeaderToResponseHeadersOwinMiddleware>(); }); //aspNetCoreApp.UseMiddleware<AddSampleHeaderToResponseHeadersAspNetCoreMiddlware>(); }
برای config مخصوص Odata، به HttpConfiguration نیاز داریم. بنابراین instanceی از آن گرفته و برای مسیریابی Odata از آن استفاده مینماییم.
با استفاده از پیاده سازی که از استاندارد Owin انجام دادیم، مشاهده کردید که Odata را همانند یک پروژهی معمولی asp.netی، config نمودیم. در خط بعدی هم SignalR را مشاهده مینمایید.
اکنون اگر آدرس زیر را در مرورگر خود وارد نمایید، پاسخ زیر را از Odata دریافت خواهید کرد:
http://localhost:YourPort/odata/Products
بعد از فرستادن request فوق، باید response زیر را دریافت نمایید:
{ "@odata.context":"http://localhost:4675/odata/$metadata#Products","value":[ { "Id":1,"Name":"Test","Price":10 } ] }
تعداد زیادی Owin Middleware موجود همانند Thinktecture IdentityServer, NWebSec, Nancy, Facebook OAuth , ... هم با همان آموزش راه اندازی بر روی Owin که دارند میتوانند در ASP.NET Core نیز استفاده شوند و زمانی که نسخهی ASP.NET Core اینها به آمادگی کامل رسید، با کمترین تغییری میتوان از آنها استفاده نمود.
var state = Battery.State; // Charging, Full, Discharging, ...
در راستای مهاجرت به ویندوز 7، کار نصب و راه اندازی SVN و کلاینتهای آن باید مجددا انجام میشد. اگر برای بار اول است که به مبحث SVN برخورد میکنید، مطالعه این جزوه توصیه میشود. مطالب ذیل برای افرادی مفید است که قصد انتقال سیستم SVN موجود خود را به مکان و یا سیستم عامل دیگری در اسرع وقت دارند.
الف) دریافت و نصب Visual SVN server
یا میتوان SVN خالص را از سایت آن دریافت کرد و یا جهت سهولت کار و همچنین دسترسی به یک کنسول مدیریتی میتوان برنامهی رایگان Visual SVN server را از آدرس زیر دریافت و نصب کرد:
پس از نصب، ابتدا باید یا کاربر جدیدی را جهت استفاده از منابع آن تعریف کرد و یا از نحوهی اعتبار سنجی یکپارچه با ویندوز هم میتوان استفاده کرد که من از این روش دوم استفاده میکنم (شکل زیر، کلیک راست بر روی نود اصلی visual SVN server و سپس انتخاب خواص و مراجعه به برگهی اعتبار سنجی آن):
ب)دریافت و نصب TortoiseSVN
نصب آن نکتهی خاصی ندارد. اما یک سری نکتهی ریز پس از نصب آن بهتر است رعایت شود که در ادامه ذکر میشود:
ج) دریافت و نصب برنامهی WinMerge
برنامهی Diff پیش فرض TortoiseSVN آنچنان قوی نیست. به همین جهت میتوان برنامهی WinMerge را با آن یکپارچه کرد. برای این منظور ابتدا آنرا دریافت نمائید:
اگر پس از نصب TortoiseSVN آنرا نصب کنید، در حین نصب پیشنهاد یکپارچه سازی با TortoiseSVN را نیز میدهد. اگر ابتدا WinMerge را نصب کردهاید و سپس TortoiseSVN بر روی سیستم شما نصب شده، فقط کافی است مطابق شکل زیر ابتدا به قسمت Diff viewers آن مراجعه کرده و سپس با انتخاب گزینهی external ، دستور خط فرمان زیر را وارد نمائید:
بدیهی است مسیر WinMergeU.exe مطابق مسیر نصب در سیستم شما باید تنظیم شود.
د) تنظیم مسیر تحت نظر قرار گرفتن سیستم
TortoiseSVN به صورت پیش فرض کل سیستم را جهت مشاهدهی تغییرات تحت نظر قرار میدهد که گاهی باعث کاهش کارآیی آن خواهد شد. برای رفع این مشکل میتوان مسیرهایی را که پروژههای شما در آن قرار دارند را به آن معرفی نمود تا بار کلی سیستم کاهش یابد.
همانطور که در شکل نیز ملاحظه میکنید، Include path مقدار دهی شده است.
ه) مشخص سازی پسوندهایی که بهتر است از آنها صرفنظر شود
به برگهی general تنظیمات TortoiseSVN مراجعه کرده و در قسمت global ignore pattern آن، موارد زیر را وارد نمائید:
این موارد شامل پروژههای دات نت، دلفی ، VC و امثال آن است و همچنین یک سری فایل بایناری که عموما با پروژههای برنامه نویسی نیازی به ثبت نگارش آنها نیست.
در همین برگه، اگر هنوز از VS2003 استفاده میکنید، تیک مربوط به استفاده از _svn بجای .svn را قرار دهید تا VS.Net با پوشههای مدیریتی ذکر شده مشکل پیدا نکند.
و) نصب افزونههای SVN سازگار با VS.Net
یا میتوان از افزونهی Visual SVN استفاده کرد (که رایگان نیست) و یا AnkhSVN که رایگان و سورس باز است.
ولی در کل یک مورد را بیشتر نصب نکنید. علت هم کند شدن VS.Net است به دلیل فعالیتهای پشت صحنهی هر کدام از این افزونهها که زیاده روی در تعداد آنها گاها باعث کرش هم میشود. بنابراین همان یک مورد کافی است.
ز) Import مخزنهای قبلی
تا اینجا مقدمات کار فراهم شد. اکنون نوبت به import مخزنهای بجا مانده از سیستم قبلی است. برای اینکار مطابق شکل زیر، گزینهی import existing repositories را انتخاب کرده و مسیر مخزنهای قبلی خود را باید معرفی نمود (به ازای هر کدام یکبار باید این عملیات صورت گیرد).
پس از انجام این مراحل یکبار باید سیستم reboot شود و اکنون همه چیز مثل قبل خواهد شد!
نکته:
اگر مسیر ریشه مخزنهای جدید با مسیر آنها در سیستم قبلی متفاوت است، هنگام commit کارهای خود با خطای زیر متوقف خواهید شد:
Unable to open repository 'file:///C:/Repositories/tracking/trunk'
اشکالی ندارد! برای رفع آن باید از گزینهی relocate مربوط به TortoiseSVN استفاده کرد.
بر روی پوشه کاری پروژه خود کلیک راست کرده، انتخاب گزینهی TortoiseSVN و سپس انتخاب گزینهی Relocate آن باید صورت گیرد. در اینجا میتوان مسیر جدید ریشه اصلی مخزن را در سیستم جدید معرفی کرد.
یکی از مشکلاتی که استفاده از VB.NET به همراه دارد عدم ارائه VB Runtime assembly در سکوهای کاری مختلف است؛ برای مثال جهت Windows Phone 7 و XNA. به همین جهت استفاده از این زبان و امکانات آن در سکوهای کاری یاد شده با مشکل روبرو بوده و سرویس پک یک VS 2010 با ارائه حالت ویژهای از کامپایل، امکان قرار دادن اسمبلی یاد شده در فایل اجرایی نهایی را میسر کرده است. برای این منظور تنها کافی است سطر ذیل به فایل vbproj اضافه گردد:
<VBRuntime>Embed</VBRuntime>
/vbruntime*
ماخذ: (+)