تنها قسمتی که تو این پست نذاشتم(و البته نیاز هم نبود) View ش بود.
@model DotnetDevBlog.Web.Models.UserViewModel @{ ViewBag.Title = "Index"; } <h2>Index</h2> @Html.DisplayForModel()
@model DotnetDevBlog.Web.Models.UserViewModel @{ ViewBag.Title = "Index"; } <h2>Index</h2> @Html.DisplayForModel()
namespace PluginsBase { public interface IPlugin { string Name { get; } void Run(); } }
using PluginsBase; namespace Plugin1 { public class Plugin1Main : IPlugin { public string Name { get { return "Test 1"; } } public void Run() { // todo: ... } } }
Copy "$(ProjectDir)$(OutDir)$(TargetName).*" "$(SolutionDir)WinFormsWithPluginSupport\bin\debug\Plugins"
Copy "$(ProjectDir)$(OutDir)*.*" "$(SolutionDir)WinFormsWithPluginSupport\bin\debug\Plugins"
PM> install-package structuremap
using System.IO; using System.Windows.Forms; using PluginsBase; using StructureMap.Configuration.DSL; using StructureMap.Graph; namespace WinFormsWithPluginSupport.Core { public class PluginsRegistry : Registry { public PluginsRegistry() { this.Scan(scanner => { scanner.AssembliesFromPath( path: Path.Combine(Application.StartupPath, "plugins"), // یک اسمبلی نباید دوبار بارگذاری شود assemblyFilter: assembly => { return !assembly.FullName.Equals(typeof(IPlugin).Assembly.FullName); }); scanner.AddAllTypesOf<IPlugin>().NameBy(item => item.FullName); }); } } }
using System; using System.Threading; using StructureMap; namespace WinFormsWithPluginSupport { public static class IocConfig { private static readonly Lazy<Container> _containerBuilder = new Lazy<Container>(defaultContainer, LazyThreadSafetyMode.ExecutionAndPublication); public static IContainer Container { get { return _containerBuilder.Value; } } private static Container defaultContainer() { return new Container(x => { x.AddRegistry<PluginsRegistry>(); }); } } }
using System.Windows.Forms; using StructureMap; namespace WinFormsWithPluginSupport { public partial class FrmMain : Form { private readonly IContainer _container; public FrmMain(IContainer container) { _container = container; InitializeComponent(); } } }
using System; using System.Windows.Forms; namespace WinFormsWithPluginSupport { static class Program { [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(IocConfig.Container.GetInstance<FrmMain>()); } } }
using System.Linq; using System.Windows.Forms; using PluginsBase; using StructureMap; using WinFormsWithPluginSupport.Core; namespace WinFormsWithPluginSupport { public partial class FrmMain : Form { private readonly IContainer _container; public FrmMain(IContainer container) { _container = container; InitializeComponent(); } private void BtnRun_Click(object sender, System.EventArgs e) { var plugins = _container.GetAllInstances<IPlugin>().ToList(); foreach (var plugin in plugins) { plugin.Run(); } } private void BtnReload_Click(object sender, System.EventArgs e) { _container.EjectAllInstancesOf<IPlugin>(); _container.Configure(x => x.AddRegistry<PluginsRegistry>() ); } } }
using System.AddIn.Pipeline;
using System.AddIn.Contract;
namespace CalculatorConract
{
[AddInContract]
public interface ICalculatorContract : IContract
{
double Operate(string operation, double a, double b);
}
}
using System;
using CalculatorConract.AddInViews;
using System.AddIn;
namespace CalculatorAddIn
{
[AddIn]
public class MyCalculatorAddIn : ICalculator
{
public double Operate(string operation, double a, double b)
{
throw new NotImplementedException();
}
}
}
using System;
using CalculatorConract.AddInViews;
using System.AddIn;
namespace CalculatorAddIn
{
[AddIn("افزونه یک", Description = "توضیحات", Publisher = "نویسنده", Version = "نگارش یک")]
public class MyCalculatorAddIn : ICalculator
{
public double Operate(string operation, double a, double b)
{
switch (operation)
{
case "+":
return a + b;
case "-":
return a - b;
case "*":
return a * b;
default:
throw new NotSupportedException("عملیات مورد نظر توسط این افزونه پشتیبانی نمیشود");
}
}
}
}
using System;
using System.AddIn.Hosting;
using CalculatorConract.HostViews;
namespace Calculator
{
class Program
{
private static ICalculator _calculator;
static void doOperation()
{
Console.WriteLine("1+2: {0}", _calculator.Operate("+", 1, 2));
}
static void Main(string[] args)
{
//مسیر پوشه ریشه مربوطه به خط لوله افزونهها
string path = Environment.CurrentDirectory;
//مشخص سازی مسیر خواندن و کش کردن افزونهها
AddInStore.Update(path);
//یافتن افزونههایی سازگار با شرایط قرارداد پروژه
//در اینجا هیچ افزونهای بارگذاری نمیشود
var addIns = AddInStore.FindAddIns(typeof(ICalculator), path);
//اگر افزونهای یافت شد
if (addIns.Count > 0)
{
var addIn = addIns[0]; //استفاده از اولین افزونه
Console.WriteLine("1st addIn: {0}", addIn.Name);
//فعال سازی افزونه و همچنین مشخص سازی سطح دسترسی آن
_calculator = addIn.Activate<ICalculator>(AddInSecurityLevel.Intranet);
//یک نمونه از استفاده آن
doOperation();
}
Console.WriteLine("Press a key...");
Console.ReadKey();
}
}
}
//فعال سازی افزونه و همچنین مشخص سازی سطح دسترسی آن
//همچنین جدا سازی پروسه اجرایی افزونه از هاست
_calculator = addIn.Activate<ICalculator>(
new AddInProcess(),
AddInSecurityLevel.Intranet);
در تصویر بالا دو مسیر با آدرسهای : ShowPage1/ و ShowPage2/ تعریف شده است که هر کدام به یک view مشخص و یک Controller برای مدیریت آن اشاره میکند.
زمانی که ما از تزریق وابستگیها در AngularJs استفاده میکنیم و یک شیء را به کنترلر تزریق میکنیم، Angular توسط Injector$ سعی در پیدا کردن وابستگی مربوطه و سپس تزریق آن به کنترلر را انجام میدهد. برای استفاده از امکان مسیریابی Route ، ما نیز باید از پروایدر مخصوص آن برای تزریق استفاده کنیم. در Angular مسیرهای برنامه توسط پروایدری به نام routeProvider$ شناسایی میشود که خدمات مسیریابی را به ما ارائه میدهد. این سرویس به ما کمک میکند تا بتوانیم اتصال بین کنترلر ها، ویوها و آدرس URL جاری مرورگرها را به آسانی برقرار کنیم.
بهتر است کار را شروع کنیم . یک فایل JS ایجاد و سپس محتویات زیر را در آن قرار دهید :
var myFirstRoute = angular.module('myFirstRoute', []); myFirstRoute.config(['$routeProvider', function($routeProvider) { $routeProvider. when('/pageOne', { templateUrl: 'templates/page_one.html', controller: 'ShowPage1Controller' }). when('/pageTwo', { templateUrl: 'templates/page_two.html', controller: 'ShowPage2Controller' }). otherwise({ redirectTo: '/pageOne' }); }]); myFirstRoute.controller('ShowPage1Controller', function($scope) { $scope.message = 'Content of page-one.html'; }); myFirstRoute.controller('ShowPage2Controller', function($scope) { $scope.message = 'Content of page-two.html'; });
در کدهای بالا ابتدا یک ماژول تعریف کرده ایم و سپس توسط ()config. تنظیمات مربوط به مسیریابی را انجام داده ایم. با استفاده از متدهای when. و otherwise. میتوانیم مسیرها را تعریف کنیم. برای هر مسیر دو پارامتر وجود دارد که اولین پارامتر نام مسیر و دومین پارامتر شامل 2 قسمت میشود که templateUrl آن آدرسی که باز خواهد شد و controller نیز نام کنترلری که ویو را مدیریت میکند.
توسط otherwise میتوانیم مسیر پیشفرض را نیز تعریف کنیم تا درصورتی که مسیری با آدرسهای بالای آن مطابقت نداشت به این آدرس منتقل شود.
در قطعه کد بالا همچنین دو مسیر با نامهای pageOne/ و pageTwo/ تعریف کرده ایم که هر کدام به ترتیب به Viewهای : templates/page_one.html و templates/page_two.html مرتبط شده اند. همچنین دو کنترلر برای مدیریت ویوها نیز تعریف شده است.
زمانی که ما آدرس http://appname/#pageOne را در نوار آدرس مرورگر وارد میکنیم، Angular به صورت اتوماتیک آدرس URL را با تنظیماتی که ما در اینجا تعریف کرده ایم مطابقت میدهد و در صورت وجود چنین آدرسی ، view مربوطه را بارگزاری میکند و در این مثال نیز مطابق با تنظیمات بالا، صفحهی templates/page_one.html برای ما بارگزاری و سپس کنترلر ShowPage1Controller را فراخوانی میکند ، جایی که ما منطق کار را در آن قرار میدهیم.
محتویات فایل main.html :
<body ng-app="app"> <div> <div> <div> <ul> <li><a href="#pageOne"> Show page one </a></li> <li><a href="#pageTwo"> Show page two </a></li> </ul> </div> <div> <div ng-view></div> </div> </div> </div> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script> <script src="app.js"></script> </body>
در قطعه کد بالا دو لینک تعریف شده است که ویژگی href از علامت هش و نام صفحه تشکیل شده است. یکی از چیزهایی که شایان ذکر است ، دایرکتیو ng-view است. مکانی برای بارگزاری صفحات در آن.
ما میتوانیم این تگ را به سه شکل زیر نیز استفاده کنیم :
<div ng-view></div> .. <ng-view></ng-view> .. <div class="ng-view"></div>
محتویات صفحه templates/page_one.html :
<h2>Page One</h2> {{ message }}
محتویات صفحه templates/page_two.html :
<h2>Page Two</h2> {{ message }}
حال اگر پروژه را اجرا کنید و به کنسول مرور گر خود نگاه کنید متوجه میشوید که مسیریاب از مسیر پیشفرض استفاده کرده است و صفحهی page_one.html را به صورت ایجکسی فراخوانی کرده است :
و اگر روی لینک Show Page two کلیک کنید ، صفحهی page_two.html نیز به صورت ایجکسی فراخوانی میشود.
دوباره بر روی لینک Show page one کلیک کنید. بله. هیچ درخواستی به سمت سرور ارسال نشد و صفحهی page_one.html به خوبی نمایش داده شد. یکی از مزیتهای سیستم مسیریابی قابلیت کش کردن صفحات است تا در صورت فراخوانی مجدد، درخواستی به سمت سرور ارسال نشود و خیلی سریع به شما نمایش داده شود.
مثال این مطلب : RouteExample.zip
ادامه دارد ...
>ng g m UploadFile -m app.module --routing
>ng g c UploadFile/UploadFileSimple
>ng g cl UploadFile/Ticket
export class Ticket { constructor(public description: string = "") {} }
import { Ticket } from "./../ticket"; export class UploadFileSimpleComponent implements OnInit { model = new Ticket();
<div class="container"> <h3>Support Form</h3> <form #form="ngForm" (submit)="submitForm(form)" novalidate> <div class="form-group" [class.has-error]="description.invalid && description.touched"> <label class="control-label">Description</label> <input #description="ngModel" required type="text" class="form-control" name="description" [(ngModel)]="model.description"> <div *ngIf="description.invalid && description.touched"> <div class="alert alert-danger" *ngIf="description.errors.required"> description is required. </div> </div> </div> <div class="form-group"> <label class="control-label">Screenshot(s)</label> <input #screenshotInput required type="file" multiple (change)="fileChange($event)" class="form-control" name="screenshot"> </div> <button class="btn btn-primary" [disabled]="form.invalid" type="submit">Ok</button> </form> </div>
(change)="fileChange($event)"
fileChange(event) { const filesList: FileList = event.target.files; console.log("fileChange() -> filesList", filesList); }
C:\Program Files (x86)\Microsoft VS Code\resources\app\extensions\node_modules\typescript\lib\lib.dom.d.ts
{ "lib": [ "es2016", "dom" ] } }
import { Component, OnInit, ViewChild, ElementRef } from "@angular/core"; export class UploadFileSimpleComponent implements OnInit { @ViewChild("screenshotInput") screenshotInput: ElementRef; submitForm(form: NgForm) { const fileInput: HTMLInputElement = this.screenshotInput.nativeElement; console.log("fileInput.files", fileInput.files); }
>ng g s UploadFile/UploadFileSimple -m upload-file.module
import { Http, RequestOptions, Response, Headers } from "@angular/http"; import { Injectable } from "@angular/core"; import { Observable } from "rxjs/Observable"; import "rxjs/add/operator/do"; import "rxjs/add/operator/catch"; import "rxjs/add/observable/throw"; import "rxjs/add/operator/map"; import "rxjs/add/observable/of"; import { Ticket } from "./ticket"; @Injectable() export class UploadFileSimpleService { private baseUrl = "api/SimpleUpload"; constructor(private http: Http) {} private extractData(res: Response) { const body = res.json(); return body || {}; } private handleError(error: Response): Observable<any> { console.error("observable error: ", error); return Observable.throw(error.statusText); } postTicket(ticket: Ticket, filesList: FileList): Observable<any> { if (!filesList || filesList.length === 0) { return Observable.throw("Please select a file."); } const formData: FormData = new FormData(); for (const key in ticket) { if (ticket.hasOwnProperty(key)) { formData.append(key, ticket[key]); } } for (let i = 0; i < filesList.length; i++) { formData.append(filesList[i].name, filesList[i]); } const headers = new Headers(); headers.append("Accept", "application/json"); const options = new RequestOptions({ headers: headers }); return this.http .post(`${this.baseUrl}/SaveTicket`, formData, options) .map(this.extractData) .catch(this.handleError); } }
postTicket(ticket: Ticket, filesList: FileList): Observable<any> { const formData: FormData = new FormData(); for (const key in ticket) { if (ticket.hasOwnProperty(key)) { formData.append(key, ticket[key]); } }
for (let i = 0; i < filesList.length; i++) { formData.append(filesList[i].name, filesList[i]); }
const headers = new Headers(); headers.append("Accept", "application/json"); const options = new RequestOptions({ headers: headers }); return this.http .post(`${this.baseUrl}/SaveTicket`, formData, options) .map(this.extractData) .catch(this.handleError);
import { UploadFileSimpleService } from "./../upload-file-simple.service"; export class UploadFileSimpleComponent implements OnInit { constructor(private uploadService: UploadFileSimpleService ) {}
submitForm(form: NgForm) { const fileInput: HTMLInputElement = this.screenshotInput.nativeElement; console.log("fileInput.files", fileInput.files); this.uploadService .postTicket(this.model, fileInput.files) .subscribe(data => { console.log("success: ", data); }); }
namespace AngularTemplateDrivenFormsLab.Models { public class Ticket { public int Id { set; get; } public string Description { set; get; } } }
using System.IO; using System.Threading.Tasks; using AngularTemplateDrivenFormsLab.Models; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc; namespace AngularTemplateDrivenFormsLab.Controllers { [Route("api/[controller]")] public class SimpleUploadController : Controller { private readonly IHostingEnvironment _environment; public SimpleUploadController(IHostingEnvironment environment) { _environment = environment; } [HttpPost("[action]")] public async Task<IActionResult> SaveTicket(Ticket ticket) { //TODO: save the ticket ... get id ticket.Id = 1001; var uploadsRootFolder = Path.Combine(_environment.WebRootPath, "uploads"); if (!Directory.Exists(uploadsRootFolder)) { Directory.CreateDirectory(uploadsRootFolder); } var files = Request.Form.Files; foreach (var file in files) { //TODO: do security checks ...! if (file == null || file.Length == 0) { continue; } var filePath = Path.Combine(uploadsRootFolder, file.FileName); using (var fileStream = new FileStream(filePath, FileMode.Create)) { await file.CopyToAsync(fileStream).ConfigureAwait(false); } } return Created("", ticket); } } }
SaveTicket(Ticket ticket)
formData.append(filesList[i].name, filesList[i]);
var files = Request.Form.Files; foreach (var file in files)
public static void Function_A() { lock (resource_1) { Thread.Sleep(1000); lock (resource_ 2) { } } } public static void Function_B() { lock (resource_2) { Thread.Sleep(1000); lock (resource_1) { } } } static void Main() { Thread thread_A = new Thread((ThreadStart)Function_A); Thread thread_B = new Thread((ThreadStart)Function_B); thread_A.Start(); thread_B.Start(); while (true) { // Stare at the two threads in deadlock. } }
if (x == 5) { y = x * 2; }
@model Plugin1.Models.Post @{ Layout = "~/Views/Shared/_Layout.cshtml"; } @Model.Title
CREATE TABLE cd.members ( memid integer NOT NULL, surname character varying(200) NOT NULL, firstname character varying(200) NOT NULL, address character varying(300) NOT NULL, zipcode integer NOT NULL, telephone character varying(20) NOT NULL, recommendedby integer, joindate timestamp not null, CONSTRAINT members_pk PRIMARY KEY (memid), CONSTRAINT fk_members_recommendedby FOREIGN KEY (recommendedby) REFERENCES cd.members(memid) ON DELETE SET NULL );
CREATE TABLE cd.facilities ( facid integer NOT NULL, name character varying(100) NOT NULL, membercost numeric NOT NULL, guestcost numeric NOT NULL, initialoutlay numeric NOT NULL, monthlymaintenance numeric NOT NULL, CONSTRAINT facilities_pk PRIMARY KEY (facid) );
CREATE TABLE cd.bookings ( bookid integer NOT NULL, facid integer NOT NULL, memid integer NOT NULL, starttime timestamp NOT NULL, slots integer NOT NULL, CONSTRAINT bookings_pk PRIMARY KEY (bookid), CONSTRAINT fk_bookings_facid FOREIGN KEY (facid) REFERENCES cd.facilities(facid), CONSTRAINT fk_bookings_memid FOREIGN KEY (memid) REFERENCES cd.members(memid) );
namespace EFCorePgExercises.Entities { public class Member { public int MemId { set; get; } public string Surname { set; get; } public string FirstName { set; get; } public string Address { set; get; } public int ZipCode { set; get; } public string Telephone { set; get; } public virtual ICollection<Member> Children { get; set; } public virtual Member Recommender { set; get; } public int? RecommendedBy { set; get; } public DateTime JoinDate { set; get; } public virtual ICollection<Booking> Bookings { set; get; } } }
namespace EFCorePgExercises.Entities { public class Facility { public int FacId { set; get; } public string Name { set; get; } public decimal MemberCost { set; get; } public decimal GuestCost { set; get; } public decimal InitialOutlay { set; get; } public decimal MonthlyMaintenance { set; get; } public virtual ICollection<Booking> Bookings { set; get; } } }
namespace EFCorePgExercises.Entities { public class Booking { public int BookId { set; get; } public int FacId { set; get; } public virtual Facility Facility { set; get; } public int MemId { set; get; } public virtual Member Member { set; get; } public DateTime StartTime { set; get; } public int Slots { set; get; } } }
namespace EFCorePgExercises.Entities { public class MemberConfiguration : IEntityTypeConfiguration<Member> { public void Configure(EntityTypeBuilder<Member> builder) { builder.HasKey(member => member.MemId); builder.Property(member => member.MemId).IsRequired().UseIdentityColumn(seed: 0, increment: 1); builder.Property(member => member.Surname).HasMaxLength(200).IsRequired(); builder.Property(member => member.FirstName).HasMaxLength(200).IsRequired(); builder.Property(member => member.Address).HasMaxLength(300).IsRequired(); builder.Property(member => member.ZipCode).IsRequired(); builder.Property(member => member.Telephone).HasMaxLength(20).IsRequired(); builder.HasIndex(member => member.RecommendedBy); builder.HasOne(member => member.Recommender) .WithMany(member => member.Children) .HasForeignKey(member => member.RecommendedBy); builder.Property(member => member.JoinDate).IsRequired(); builder.HasIndex(member => member.JoinDate).HasName("IX_JoinDate"); builder.HasIndex(member => member.RecommendedBy).HasName("IX_RecommendedBy"); } } }
namespace EFCorePgExercises.Entities { public class FacilityConfiguration : IEntityTypeConfiguration<Facility> { public void Configure(EntityTypeBuilder<Facility> builder) { builder.HasKey(facility => facility.FacId); builder.Property(facility => facility.FacId).IsRequired().UseIdentityColumn(seed: 0, increment: 1); builder.Property(facility => facility.Name).HasMaxLength(100).IsRequired(); builder.Property(facility => facility.MemberCost).IsRequired().HasColumnType("decimal(18, 6)"); builder.Property(facility => facility.GuestCost).IsRequired().HasColumnType("decimal(18, 6)"); builder.Property(facility => facility.InitialOutlay).IsRequired().HasColumnType("decimal(18, 6)"); builder.Property(facility => facility.MonthlyMaintenance).IsRequired().HasColumnType("decimal(18, 6)"); } } }
namespace EFCorePgExercises.Entities { public class BookingConfiguration : IEntityTypeConfiguration<Booking> { public void Configure(EntityTypeBuilder<Booking> builder) { builder.HasKey(booking => booking.BookId); builder.Property(booking => booking.BookId).IsRequired().UseIdentityColumn(seed: 0, increment: 1); builder.Property(booking => booking.FacId).IsRequired(); builder.HasOne(booking => booking.Facility) .WithMany(facility => facility.Bookings) .HasForeignKey(booking => booking.FacId); builder.Property(booking => booking.MemId).IsRequired(); builder.HasOne(booking => booking.Member) .WithMany(member => member.Bookings) .HasForeignKey(booking => booking.MemId); builder.Property(booking => booking.StartTime).IsRequired(); builder.Property(booking => booking.Slots).IsRequired(); builder.HasIndex(booking => new { booking.MemId, booking.FacId }).HasName("IX_memid_facid"); builder.HasIndex(booking => new { booking.FacId, booking.StartTime }).HasName("IX_facid_starttime"); builder.HasIndex(booking => new { booking.MemId, booking.StartTime }).HasName("IX_memid_starttime"); builder.HasIndex(booking => booking.StartTime).HasName("IX_starttime"); } } }
namespace EFCorePgExercises.DataLayer { public class ApplicationDbContext : DbContext { public ApplicationDbContext(DbContextOptions options) : base(options) { } public DbSet<Member> Members { get; set; } public DbSet<Booking> Bookings { get; set; } public DbSet<Facility> Facilities { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); modelBuilder.ApplyConfigurationsFromAssembly(typeof(MemberConfiguration).Assembly); } } }
dotnet tool install --global dotnet-ef --version 3.1.6 dotnet tool update --global dotnet-ef --version 3.1.6 dotnet build dotnet ef migrations add Init --context ApplicationDbContext
context.Facilities.Add(new Facility { Name = "Tennis Court 1", MemberCost = 5, GuestCost = 25, InitialOutlay = 10000, MonthlyMaintenance = 200 }); // مابقی موارد context.SaveChanges();
context.Members.Add(new Member { ... }); context.SaveChanges(); // For id = 0 = Int's CLR Default Value!
using (var transaction = context.Database.BeginTransaction()) { try { context.Database.ExecuteSqlRaw("SET IDENTITY_INSERT Members ON"); context.Members.Add(new Member { ... }); // مابقی موارد context.SaveChanges(); transaction.Commit(); } catch { transaction.Rollback(); throw; } finally { context.Database.ExecuteSqlRaw("SET IDENTITY_INSERT Members OFF"); } }