مگه اینترفیس فقط امضا روالها رو نداره؟ پس یک کلاس نیاز داره که بتونه اون متدها رو پیاده سازی کنه و ما ازش استفاده کنیم
غیر از اینه؟
پس در کد زیر
IJobDetail job = JobBuilder.Create<HelloJob>()
مجبوریم از اینترفیس به عنوان متغیر استفاده کنیم؟
EF Code First #12
در اینصورت به پیاده سازی متد SaveChanges اینترفیس IUnitOfWork باید Overrides هم اضافه بشه که کامپایلر بدونه متد SaveChanges اینترفیس IUnitOfWork متد SaveChanges کلاس DbContext رو تحریف کرده،درسته؟
- اگر هاست شما تمام سایتها را با یک Application pool مدیریت میکند، کرش یکی از چند ده سایت دیگر میتواند سبب ریاستارت شدن سایت شما هم بشود؛ چون برنامهها از همه ایزوله نشدهاند. راه حل آن ایجاد یک Application pool مجزا به ازای هر سایت هست (توسط هاستدار).
زمانیکه تمام سایتها با یک Application pool واحد مدیریت میشوند، تمام آنها توسط یک وهله از w3wp.exe اجرا خواهند شد. با تعریف Application poolهای مجزا، هر سایت، یک وهلهی مجزا از w3wp.exe را به خود اختصاص خواهد داد. یعنی اگر Task manager سرور را بررسی کنید، به ازای هر سایت، یک w3wp.exe با pid مجزا قابل مشاهده است. به این ترتیب اگر pid=1234 کرش کرد، تاثیری روی pid=4321 نخواهد داشت.
- یک برنامهی ASP.NET پس از مدتی بیکاری (قابل تنظیم در Application pool برنامه)، به صورت خودکار توسط IIS از حافظه خارج میشود. با درخواست بعدی که به آن برنامه میرسد (مثلا گشودن یک صفحهی آن توسط یک کاربر)، مجددا از صفر اجرا خواهد شد. این مورد نیز به معنای ریاستارت کامل برنامه است.
- در تنظیمات Application pool موارد زیادی را میتوان تنظیم کرد که سبب ریاستارت شدن برنامه میشوند. برای مثال اگر مصرف CPU و یا حافظهی برنامه به حد مشخصی رسید، برنامه ریاستارت شود و امثال آن.
ASP.NET Web API - قسمت اول
function identity(arg: number): number { return arg; }
function identity(arg: any): any { return arg; }
function identity<T>(arg: T): T { return arg; }
- ارسال تمام آرگومانها که شامل آرگومان نوع داده هم میباشد
let output = identity<string>("myString"); // type of output will be 'string'
- روش دوم که شاید استفاده رایج از توابع جنریک هم هست، استفاده از امکان type argument inference میباشد.
let output = identity("myString"); // type of output will be 'string'
function loggingIdentity<T>(arg: T): T { console.log(arg.length); // Error: T doesn't have .length return arg; }
function loggingIdentity<T>(arg: T[]): T[] { console.log(arg.length); // Array has a .length, so no more error return arg; }
function loggingIdentity<T>(arg: Array<T>): Array<T> { console.log(arg.length); // Array has a .length, so no more error return arg; }
function identity<T>(arg: T): T { return arg; } let myIdentity: <T>(arg: T) => T = identity;
function identity<T>(arg: T): T { return arg; } let myIdentity: <U>(arg: U) => U = identity;
function identity<T>(arg: T): T { return arg; } let myIdentity: {<T>(arg: T): T} = identity;
interface GenericIdentityFn { <T>(arg: T): T; } function identity<T>(arg: T): T { return arg; } let myIdentity: GenericIdentityFn = identity;
interface GenericIdentityFn<T> { (arg: T): T; } function identity<T>(arg: T): T { return arg; } let myIdentity: GenericIdentityFn<number> = identity;
class GenericNumber<T> { zeroValue: T; add: (x: T, y: T) => T; } let myGenericNumber = new GenericNumber<number>(); myGenericNumber.zeroValue = 0; myGenericNumber.add = function(x, y) { return x + y; };
let stringNumeric = new GenericNumber<string>(); stringNumeric.zeroValue = ""; stringNumeric.add = function(x, y) { return x + y; }; alert(stringNumeric.add(stringNumeric.zeroValue, "test"));
interface Lengthwise { length: number; } function loggingIdentity<T extends Lengthwise>(arg: T): T { console.log(arg.length); // Now we know it has a .length property, so no more error return arg; }
loggingIdentity(3); // Error, number doesn't have a .length property
loggingIdentity({length: 10, value: 3});
function find<T, U extends Findable<T>>(n: T, s: U) { // errors because type parameter used in constraint // ... } find (giraffe, myAnimals);
function find<T>(n: T, s: Findable<T>) { // ... } find(giraffe, myAnimals);
function create<T>(c: {new(): T; }): T { return new c(); }
class BeeKeeper { hasMask: boolean; } class ZooKeeper { nametag: string; } class Animal { numLegs: number; } class Bee extends Animal { keeper: BeeKeeper; } class Lion extends Animal { keeper: ZooKeeper; } function findKeeper<A extends Animal, K> (a: {new(): A; prototype: {keeper: K}}): K { return a.prototype.keeper; }
findKeeper(Lion).nametag; // typechecks!
ما در AngularJs آبجکتی را به نام q$ داریم که برای اجرای توابع به صورت async مفید است و همچنین در استفاده از مقادیر برگشتی از این درخواستها برای پردازشهای آینده به ما کمک میکند. برای اطلاعات بیشتر در مورد این سرویس به اینجا مراجعه کنید.
در ادامه ما از تابع ()all از q$ برای ترکیب چند شیء promise داخل یک شیء promise، به منظور صدا زدن چند سرویس به صورت یکجا، استفاده میکنیم.
پیاده سازی ASP.NET Web API
قدم اول : Visual Studio را بازکنید و یک پروژه empty ASP.NET Web API را مطابق شکل زیر ایجاد کنید.
using System.Collections.Generic; namespace NG_Combine_Multiple_Promises.Models { public class Courses { public int CourseId { get; set; } public string CourseName { get; set; } } public class CourseDatabase : List<Courses> { public CourseDatabase() { Add(new Courses() { CourseId=1,CourseName="الکترونیک"}); Add(new Courses() { CourseId = 2, CourseName = "ریاضی 2" }); Add(new Courses() { CourseId = 3, CourseName = "طراحی نرم افزار" }); } } public class Student { public int StudentId { get; set; } public string Name { get; set; } public string AcadmicYear { get; set; } } public class StudentDatabase : List<Student> { public StudentDatabase() { Add(new Student() {StudentId=101,Name="محمد علوی", AcadmicYear="اول" }); Add(new Student() { StudentId = 102, Name = "طاهره موسوی", AcadmicYear = "دوم" }); Add(new Student() { StudentId = 103, Name = "علی عباسی", AcadmicYear = "سوم" }); Add(new Student() { StudentId = 104, Name = "جواد نوری", AcadmicYear = "اول" }); Add(new Student() { StudentId = 105, Name = "محسن خدایی", AcadmicYear = "دوم" }); Add(new Student() { StudentId = 106, Name = "علی کاظمی", AcadmicYear = "سوم" }); Add(new Student() { StudentId = 107, Name = "زهرا مقدم", AcadmicYear = "اول" }); Add(new Student() { StudentId = 108, Name = "لاله فکور", AcadmicYear = "دوم" }); Add(new Student() { StudentId = 109, Name = "علی نوروزی", AcadmicYear = "چهارم" }); } } }
کد بالا شامل موجودیتهای Courses و Student است و کلاسهای CourseDatabase و StudentDatabase به ترتیب برای ذخیره این موجودیتها است.
قدم سوم : بستهی نیوگت Microsoft.AspNet.WebAPi.Cors را با استفاده از NuGet Package Manager، به منظور فعال سازی امکان صدا زدن این وب سرویس از دامنههای مختلف، به پروژه اضافه کرده و کد زیر را در کلاس WebApiCofig در پوشه App_Start قرار دهید.
config.EnableCors();
قدم چهارم : دو کنترل از نوع Web API 2 Empty را با نامهای CourseAPIController و StudentAPIController ایجاد کرده و کدهای زیر را در آنها قرار دهید.
CourseAPIController.cs
[EnableCors("*","*","*")] public class CourseAPIController : ApiController { [Route("Courses")] public IEnumerable<Courses> Get() { return new CourseDatabase(); } }
StudentAPIController.cs
[EnableCors("*", "*", "*")] public class StudentAPIController : ApiController { [Route("Students")] public IEnumerable<Student> Get() { return new StudentDatabase(); } }
استفاده از Angular $q.all
قدم اول : پروژهی جدیدی را از نوع Empty ASP.NET در همین solution اضافه کرده و ارجاعات jQuery, Bootstrap و AngularJS را با استفاده از NuGet Package manager مانند زیر اضافه کنید:
Install-Package jQuery Install-Package bootstrap Install-Package angularjs
قدم دوم : پوشهایی را به نام MyScripts ایجاد کرده و درون آن فایل javascript زیر را با نام logic.js اضافه کنید:
var app = angular.module('mymodule', []); //سرویسی برای بازگرداندن لیست دروس app.service('courseService', function ($http) { this.get = function () { var response = $http.get("http://localhost:11696/Courses"); return response; }; }); //سرویسی برای بازگرداندن لیست دانشجویان app.service('studentService', function ($http) { this.get = function () { var response = $http.get("http://localhost:11696/Students"); return response; }; }); //تعریف کنترلر app.controller('ctrl', function ($scope, $q, courseService, studentService) { $scope.Courses = []; $scope.Students = []; loadData(); /**/ function loadData() { var promiseCourse = courseService.get(); var promiseStudent = studentService.get(); $scope.combineResult = $q.all([ promiseCourse, promiseStudent ]).then(function (resp) { $scope.Courses = resp[0].data; $scope.Students = resp[1].data; }); } });
<!DOCTYPE html> <html ng-app="mymodule"> <head> <title></title> <meta charset="utf-8" /> <link href="../Content/bootstrap.min.css" rel="stylesheet" /> <script src="../Scripts/jquery-3.2.1.min.js"></script> <script src="../Scripts/angular.min.js"></script> <script src="../MyScripts/logic.js"></script> </head> <body ng-controller="ctrl"> <div class="container"> <h1 class="h1">دروس</h1> <table class="table table-striped table-bordered table-condensed"> <thead> <tr> <td class="text-center">کد درس</td> <td class="text-center">نام درس</td> </tr> </thead> <tbody> <tr ng-repeat="Course in Courses"> <td class="text-center">{{Course.CourseId}}</td> <td class="text-center">{{Course.CourseName}}</td> </tr> </tbody> </table> <hr /> <h1 class="h1">دانشجویان</h1> <table class="table table-striped table-bordered table-condensed"> <thead> <tr> <td class="text-center">کد دانشجویی</td> <td class="text-center">نام و نام خانوادگی</td> <td class="text-center">سال دانشجویی</td> </tr> </thead> <tbody> <tr ng-repeat="Student in Students"> <td class="text-center">{{Student.StudentId}}</td> <td class="text-center">{{Student.Name}}</td> <td class="text-center">{{Student.AcadmicYear}}</td> </tr> </tbody> </table> </div> </body> </html>
import { MyComponent } from './../path/my.component'; @NgModule({ imports: [...], declarations: [ MyComponent], providers: [...] }) export class UsersLoginModule {}
- اما اگر قرار است در چندین ماژول استفاده شود، یکی از روشها ایجاد یک shared module (اضافه کردن آن فقط به یک تک ماژول اشتراکی) و سپس تعریف این کامپوننت در قسمت exports آن است:
import {SharedComponentA} from "./SharedComponentA"; import {SharedComponentB} from "./SharedComponentA"; @NgModule({ imports: [ ], declarations: [ SharedComponentA, SharedComponentB ], providers: [ ], exports: [ SharedComponentA, SharedComponentB ] }) export class SharedModule {}
import {SharedModule } from './SharedModule'; @NgModule({ imports: [ //... SharedModule //... ], declarations: [ // .... ], providers: [ // .... ] }) export class PersonModule{}
مدیریت سفارشی سطوح دسترسی کاربران در MVC
من فکر میکنم باید حالتهای دیگه ای رو هم بررسی کنی. مثلاً اینکه تغییر در نقش کاربر بوده یا مجوزهای نقش. اگر کاربر در حین پر کردن یک فرم AJAXیی مجوزش گرفته شد چه واکنشی باید رخ بده؟ آیا تمامی این بررسیها و پیاده سازی اونها، به ایجاد یک ارتباط ساده و واکشی مجوز جاری کاربر برای درخواست برتری دارند؟
اگر امکانش رو داری، یک بررسی زمانی بین اون سیستم مدیریت Cache (با در نظر گرفتن تمامی حالت ها) و ایجاد ارتباط ساده با پایگاه داده برای بررسی داشتن مجوز کاربر انجام بده.
Kendo UI Q2 2012 BETA available now
- برای ASP.NET MVC یک سری HTML Helper داره که استفاده ازش رو ساده میکنه (اینها هم رایگان نیستند؛ و باید مجوز آنها خریداری شود).
- یک دوره کامل Kendo UI رو میتونید اینجا پیدا کنید. البته این دوره عمومی هست و از kendo ui برای استفاده در کلیه برنامههای وب و کلیه فناوریهای سمت سرور مرتبط طراحی شده. یعنی از wrapper خاصی استفاده نکرده و از اصل کتابخانه جاوا اسکریپتی آن مستقیما استفاده کرده.