شروع کار با Angular 2
بایدها و نبایدهای استفاده از IoC Containers
- در مورد معکوس شدن مسئولیتها به تفصیل در سه قسمت اول این دوره مطلب نوشته شده است؛ پیش از شروع به کد نویسی.
- من StructureMap رو ترجیح میدم. خیلیها هم همین نظر رو دارند:
IoC libraries compared
Which .NET Dependency Injection frameworks are worth looking into
- این مورد بیشتر سلیقهای هست.
کتابخانه Brighter
The Brighter project is up on GitHub incudes a bunch of libraries and examples that you can pull in to support CQRS architectural styles in .NET.
نمونه از پیاده سازی این کتابخانه در Mvc Core
- Day One Keynote (Slides)
- Day Two Keynote
- What's New for Microsoft Silverlight and Microsoft Windows Presentation
Foundation (WPF) Developers in Microsoft Visual Studio 2010 - Semantic HTML and Unobtrusive JavaScript
- Design Fundamentals for Developers
- Microsoft Silverlight and Windows Presentation Foundation (WPF): Sharing
Skills and Code - Going Inside Microsoft Silverlight: Exploring the Core CLR
- Delivering Media with Internet Information Services 7 (IIS) Media
Services and Microsoft Silverlight - Shio O Totte: Using What You Know
- Building Data-Driven Scalable AJAX Web Pages
- Microsoft ASP.NET: Taking AJAX to the Next Level
- A Shot of Windows Live Messenger and a Pint of Microsoft Silverlight
- Automated User Interface (UI) Testing with Microsoft Visual Studio
Team System 2010 - There's a Little Scripter in All of Us: Building a Web App for the
Masses - Microsoft ASP.NET 4.0 Data Access: Patterns for Success with Web Forms
- Cascading Stylesheets
- Creating a "Next Generation" E-Commerce Experience
- Cloud Computing: What's in It for Me?
- Developing for Experience with 3 Heads
- Developing and Deploying Applications on Internet Information Services
(IIS) - Hiking Mt. Avalon
- Advance Your Design with UX Design Patterns
- Love the New Windows Live Messenger Web Toolkit for Social Websites
- Ten Ways to Ensure RIA Failure
- Using Dynamic Languages to Develop Microsoft Silverlight Applications
- Miss March and Other Distractions
- Caching REST with Windows Communication Foundation
- Designing the Windows 7 Desktop Experience
- Microsoft Silverlight Media End-to-End
- Optimizing Performance for Microsoft Expression Encoder
- Scaling a Rich Client to Half a Billion Users
- User Experience Design for Non-Designers
- Build Applications on the Microsoft Platform Using Eclipse, Java,
Ruby and PHP! - Customized Live Search for Web and Client Applications
- Building Microsoft Silverlight Controls
- Working across the Client Continuum
- Building a Rich Social Network Application
- Adding Microsoft Silverlight to Your Company's Skill Set
- Principles of Microsoft Silverlight Animation
- Oomph: A Microformat Toolkit
- Introducing the Microsoft Virtual Earth Silverlight Map Control CTP
- Delivering Ads to a Silverlight Media Player Application
- High-Speed RIA Development with the Microsoft Silverlight Toolkit
- Deep Zoom++ : Build Dynamic Deep Zoom Applications with Open Source
- See through the Clouds: Introduction to the Azure Services Platform
- Modeling RESTful Data Services: Present and Future
- Escaping Flatland in Application Design: Rich User Experiences
- Building High Performance Web Applications and Sites
- Sketch Flow: From Concept to Production
- Design Prototyping: Bringing Wireframes to Life
- Overview of Windows Azure
- A Website Named Desire
- Protecting Online Identities
- Web Form Design
- Simplifying Distributed Access Control with Microsoft .NET Services
- Software Entrepreneurs: Go Big with BizSpark
- How I Learned to Stop Worrying and Love the Microsoft ADO.NET Entity
Framework - Copyright Laws for Web Designers and Developers
- Effective Infographics with Interactivity
- State of the Art in Web Site Design on Microsoft SharePoint
- The Way of the Whiteboard: Persuading with Pictures
- Interaction Techniques Using the Wii Remote (and Other HCI Projects)
- Touch and Gesture Computing, What You Haven't Heard
- Enhancing Large Windows Media Platforms with Microsoft Silverlight
- The Future of Microsoft Expression Blend
- Exposing Web Content to a Global Audience Using Machine Translation
- Building Microsoft Silverlight Applications with Eclipse
(Slides) - Going Inside Microsoft Silverlight: Exploring the Core CLR
(Slides) - Web Development Using Microsoft Visual Studio: Now and in the Future
(Slides) - Building Amazing Business Centric Applications with Microsoft Silverlight 3
- Creating Media Content for Microsoft Silverlight Using Microsoft Expression
Encoder (Slides) - Design Prototyping: Bringing Wireframes to Life (Slides)
- Measuring Social Media Marketing (Slides)
- Mesh-Enabled Web Applications (Slides)
- .NET RIA Services - Building Data-Driven Applications with Microsoft
Silverlight and Microsoft ASP.NET (Slides) - Making XML Really, Really Easy with Microsoft Visual Basic 9
(Slides) - Building Accessible RIAs in Microsoft Silverlight
(Slides) - Integrating Microsoft Expression Blend with Adobe Creative Suite
(Slides) - Principles of Microsoft Silverlight Animation (Slides)
- Windows Mobile 6.5 Overview (Slides)
- How'd they do it? Real App. Real Code. Two Weeks. Nothing but .NET
- Building Web Applications with Windows Azure (Slides)
- Live Framework and Mesh Services: Live Services for Developers
(Slides) - Software Entrepreneurs: Go Big with BizSpark (Slides)
- Microsoft ASP.NET 4.0 : What's Next? (Slides)
- Building Out of Browser Experiences with Microsoft Silverlight 3
- The Microsoft Web Sandbox: An Open Source Framework for Developing
Secure Standards-Based Web Applications (Slides) - Enhancing Large Windows Media Platforms with Microsoft Silverlight
(Slides) - Microsoft Silverlight Media End-to-End (Slides)
- Improving UX through Application Lifecycle Management
(Slides) - Go Beyond Best Practices: Evolving Next Practices to Prosper in the
21st Century (Slides) - Creating Interactivity with Microsoft Expression Blend
(Slides) - See through the Clouds: Introduction to the Azure Services Platform
(Slides) - Overview of Windows Azure (Slides)
- What's New in Microsoft Silverlight 3 (Slides)
- the New Windows Live Messenger Web Toolkit for Social Websites
- Extending Your Brand to the Desktop with Windows 7 (Slides)
- RESTful
Services for the Programmable Web with Windows Communication Foundation
(Slides) - Securing Web Applications (Slides)
- How Razorfish Lights Up Brand with Microsoft SharePoint (Slides)
- Copyright Laws for Web Designers and Developers
- Improving Mobile Experiences with the Microsoft Mobile Device Browser
File - A Shot of Windows Live Messenger and a Pint of Microsoft Silverlight
(Slides) - Microsoft Silverlight Is Ready for Business (Slides)
- Exposing Web Content to a Global Audience Using Machine Translation
(Slides) - Search Engine Optimization (SEO) for Web Developers
- Five Killer Scenarios for the Windows Live Messenger Web Toolkit
(Slides) - Lighting Up Web and Client Applications with Microsoft Live Services
(Slides) - Scaling a Rich Client to Half a Billion Users (Slides)
- Windows Internet Explorer 8 in the Real World: How Is Internet Explorer
8 Used (Slides) - When Errors Happen: Debugging Microsoft Silverlight
(Slides) - Introducing the Microsoft Web Platform (Slides)
- Protecting Against Internet Service Abuse (Slides)
- Connecting Applications across Networks with Microsoft .NET Services
(Slides) - Microsoft Xbox "Lips" and "Fable II": Multi Channel Experiences
(Slides) - Windows Azure Storage (Slides)
- Sketch Flow: From Concept to Production (Slides)
- Consuming Web Services in Microsoft Silverlight 3
- A Website Named Desire
- The Microsoft Web Platform: Starring Internet Information Services
(IIS) and Your Application (Slides) - Microsoft ASP.NET: Taking AJAX to the Next Level
(Slides) - Using Microsoft ASP.NET MVC to Easily Extend a Web Site into the Mobile
Space (Slides) - Using Total Experience Design to Transform the Digital Building
(Slides) - Wireframes That Work: Designing (Rich Internet) Applications
(Slides) - Interactive Prototyping with DHTML
- Working across the Client Continuum (Slides)
- ASP.NET MVC: America's Next Top Model View Controller Framework
(Slides) - Microsoft Expression Web: No Platform Left Behind
(Slides) - Choosing between ASP.NET Web Forms and MVC (Slides)
- Customized Live Search for Web and Client Applications
(Slides) - Creating a Great Experience on Digg with Windows Internet Explorer 8
- C# for Designers (Slides)
- A Lap around Microsoft .NET Services (Slides)
- Building Scalable and Available Web Applications with Microsoft Project
Code Name "Velocity" (Slides) - Building an Optimized, Graphics-Intensive Application for Microsoft Silverlight
(Slides) - What's New in Microsoft SQL Data Services (Slides)
- What's New in Windows Presentation Foundation (WPF) 4 (Slides)
- A Lap around Windows Internet Explorer 8 (Slides)
- The Future of Microsoft Expression Blend (Slides)
- Running PHP on Microsoft Servers and Services (Slides)
- Delivering Media with Internet Information Services 7 (IIS) Media
Services and Microsoft Silverlight (Slides) - Deep Dive into Microsoft Silverlight Graphics (Slides)
- Microsoft ASP.NET Model View Controller (MVC): Ninja on Fire Black
Belt Tips (Slides) - Developing
RESTful Services and Clients with "M" (Slides) - User Experience Design Patterns for Business Applications with Microsoft
Silverlight 3 (Slides) - Using the Windows Azure Tools for Microsoft Visual Studio to Build
Cloud Services (Slides) - Standards for Aggregating Activity Feeds and Social Aggregation Services
- Offline
Network Detection in Microsoft Silverlight 3 (Slides) - File|New Company: Creating NerdDinner.com with Microsoft ASP.NET
Model View Controller (MVC)
در واقع ما یک سیستمی داریم که شامل مدلی است از دیتاهای ما و از این مدل برای کوئری گرفتن از دیتابیس استفاده میشود، که البته برای بیشتر پروژههای نرم افزاری، معماری درست و ترجیح داده شدهای هم میباشد.
زمانیکه نیازهای پروژه روز به روز افزورده و پیچیدهتر میشود، مدل CRUD بصورت پیوسته از ارزشش کاسته میشود و از آن سادگی اولیهی در درک و خوانایی آن دور خواهد شد.
ذات CQRS بر آن است که شما مدلهای مختلفی را برای خواندن و نوشتن دیتا داشته باشید. الگوی آن چیزی شبیه به تصویر زیر است
ES از برنامه نویسان میخواهد که مدل سنتی CRUD را فراموش کرده و بجای آن تغییراتی را که روی دیتا صورت گرفته، نیز درج نمایند. اینکار به وسیلهی یک دیتابیس Append-only انجام میشود که به نام Event Store شناخته میشود.
در این معماری ما همهی تغییرات روی دیتا را به صورت Serialize Event ذخیره میکنیم که میتواند دوباره در هر زمانی اجرا شده و current state هر objectی را در اختیار بگذارد.
این روش به ما کمک بزرگی میکند تا وضعیت یک object را در گذشته به راحتی پیدا کنیم و از آن میتوان به غیر از فوایدی که دارد، به عنوان یک Logger نیز استفاده نمود. به دلیل اینکه جزء به جزء تغییرات بر روی state سیستم، در آن ثبت شده است. از آنجاییکه دیتا بصورت serialize ذخیره میشود، بارگزاری آن نیز با سرعت بالایی انجام خواهد شد.
public class Movie : AggregateRoot { public string Title { get; set; } public DateTime ReleaseDate { get; set; } public int RunningTimeMinutes { get; set; } public Movie() { } public Movie(Guid movieId, string title, DateTime releaseDate, int runningTimeMinutes) { //پیاده سازی خواهد شد } }
public class CreateMovieCommand : ICommand { public string Title { get; set; } public DateTime ReleaseDate { get; set; } public int RunningTimeMinutes { get; set; } public CreateMovieCommand(string title, DateTime releaseDate, int runningTime) { Title = title; ReleaseDate = releaseDate; RunningTimeMinutes = runningTime; } }
public class CreateMovieCommandHandler : CommandHandler<CreateMovieCommand> { protected IDomainRepository _repository; public CreateMovieCommandHandler(IDomainRepository repository) { _repository = repository; } public override void Handle(CreateMovieCommand command) { var movie = new Domain.Movie(Guid.NewGuid(), command.Title, command.ReleaseDate, command.RunningTimeMinutes); _repository.Save(movie); } }
public class MovieCreatedEvent : DomainEvent { public Guid MovieId { get { return AggregateRootId; } set { AggregateRootId = value;} } public string Title { get; set; } public DateTime ReleaseDate { get; set; } public int RunningTimeMinutes { get; set; } public MovieCreatedEvent(Guid movieId, string title, DateTime releaseDate, int runningTime) { MovieId = movieId; Title = title; ReleaseDate = releaseDate; RunningTimeMinutes = runningTime; } }
public class Movie : AggregateRoot { public string Title { get; set; } public DateTime ReleaseDate { get; set; } public int RunningTimeMinutes { get; set; } public Movie(Guid movieId, string title, DateTime releaseDate, int runningTimeMinutes) { Apply(new MovieCreatedEvent(Guid.NewGuid(), title, releaseDate, runningTimeMinutes)); } }
public class MovieEventHandler : IHandleDomainEvents<MovieCreatedEvent> { public void Handle(MovieCreatedEvent createdEvent) { using (MoviesContext entities = new MoviesContext()) { entities.Movies.Add(new Movie() { Id = createdEvent.AggregateRootId, Title = createdEvent.Title, ReleaseDate = createdEvent.ReleaseDate, RunningTimeMinutes = createdEvent.RunningTimeMinutes }); entities.SaveChanges(); } } }
protected void OnMovieCreated(MovieCreatedEvent domainEvent) { Id = domainEvent.AggregateRootId; Title = domainEvent.Title; ReleaseDate = domainEvent.ReleaseDate; RunningTimeMinutes = domainEvent.RunningTimeMinutes; }
- ذاتا پیاده سازی این مدل سخت و دشوار است و از آنجاییکه سادگی در پیاده سازی سیستمهای نرم افزاری، یک اصل مهم محسوب میشود، بنابراین استفاده از این مدل محدود میشود به سیستمهای نرم افزاری که مزیتهای گفته شده در قسمت فوق برایشان حیاتی محسوب شود.
- برای پیاده سازی سیستمی با این مدل احتیاج به تیم توسعهای است که با مفاهیم آن کاملا آشنا باشد.
- هر چند امروزه فضای فیزیکی برای ذخیره سازی دیتا ارزان محسوب میشود، اما به هر حال استفاده از این مدل به همراه ES، حجم زیادی از Disk space را خواهد گرفت.
- همانطور که دیدید برای پیاده سازی یک Insert ساده، حجم زیادی کد نوشته شدهاست. بنابراین تولید اینگونه نرم افزارها به زمان بیشتری نیاز دارد.
در ادامه نحوه سازگار سازی این مجموعه را با ASP.NET MVC مرور خواهیم کرد:
الف) سورسهای اصلی Flash کنترل ارسال فایلها
اگر علاقمند به تغییر اطلاعاتی در فایل فلش نهایی هستید به پوشه OriginalFlashSource پروژه پیوست شده مراجعه کنید. در اینجا برای مثال یک سری از برچسبهای آن فارسی شدهاند و کامپایل مجدد.
ب) مزیت استفاده از Flash uploader
با استفاده از Flash uploader امکان انتخاب چندین فایل با هم وجود دارد. همچنین در صفحه دیالوگ انتخاب فایلها دقیقا میتوان پسوند فایلهای مورد نظر را نیز تعیین کرد. این دو مورد در حالت ارسال معمولی فایلها به سرور و استفاده از امکانات معمولی HTML وجود ندارند. به علاوه امکان نمایش درصد پیشرفت آپلود فایلها و همچنین حذف کلی لیست و حذف یک آیتم از لیست را هم درنظر بگیرید.
ج) معادل کنترل Web forms را در ASP.NET MVC به شکل زیر میتوان تهیه کرد:
@helper AddFlashUploader( string uploadUrl, string queryParameters, string flashUrl, int totalUploadSizeLimit = 0, int uploadFileSizeLimit = 0, string fileTypes = "", string fileTypeDescription = "", string onUploadComplete = "") { onUploadComplete = string.IsNullOrEmpty(onUploadComplete) ? "" : "completeFunction=" + onUploadComplete; queryParameters = Server.UrlEncode(queryParameters); fileTypes = string.IsNullOrEmpty(fileTypes) ? "" : "&fileTypes=" + Server.UrlEncode(fileTypes); fileTypeDescription = string.IsNullOrEmpty(fileTypeDescription) ? "" : "&fileTypeDescription=" + Server.UrlEncode(fileTypeDescription); var totalUploadSizeLimitData = totalUploadSizeLimit > 0 ? "&totalUploadSize=" + totalUploadSizeLimit : ""; var uploadFileSizeLimitData = uploadFileSizeLimit > 0 ? "&fileSizeLimit=" + uploadFileSizeLimit : ""; var flashVars = onUploadComplete + fileTypes + fileTypeDescription + totalUploadSizeLimitData + uploadFileSizeLimitData + "&uploadPage=" + uploadUrl + "?" + queryParameters; <object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" width="575" height="375" id="fileUpload" align="middle"> <param name="allowScriptAccess" value="sameDomain" /> <param name="movie" value="@flashUrl" /> <param name="quality" value="high" /> <param name="wmode" value="transparent"> <param name=FlashVars value="@flashVars"> <embed src="@flashUrl" FlashVars="@flashVars" quality="high" wmode="transparent" width="575" height="375" name="fileUpload" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" /> </object> }
د) نحوه استفاده از HTML helper فوق:
@{ ViewBag.Title = "Index"; var uploadUrl = Url.Action("Uploader", "Home"); var flashUrl = Url.Content("~/Content/FlashUpload/FlashFileUpload.swf"); } <h2> Flash Uploader</h2> <div style="background: #E0EBEF;"> @FlashUploadHelper.AddFlashUploader( uploadUrl: uploadUrl, queryParameters: "User=Vahid&Id=تست", flashUrl: flashUrl, fileTypeDescription: "Images", fileTypes: "*.gif; *.png; *.jpg; *.jpeg", uploadFileSizeLimit: 0, totalUploadSizeLimit: 0, onUploadComplete: "alert('انجام شد');") </div>
using System.Collections.Generic; using System.IO; using System.Web; using System.Web.Mvc; namespace MvcFlashUpload.Controllers { public class HomeController : Controller { public ActionResult Index() { return View(); } public ActionResult Uploader(string User, string Id, IEnumerable<HttpPostedFileBase> FileData) { var queryParameter1 = User; var queryParameter2 = Id; // ... foreach (var file in FileData) { if (file.ContentLength > 0) { var fileName = Path.GetFileName(file.FileName); var path = Path.Combine(Server.MapPath("~/App_Data/Uploads"), fileName); file.SaveAs(path); } } return Content(" "); } } }
توضیحات:
در اینجا uploadUrl، مسیر اکشن متدی است که قرار است اطلاعات فایلها را دریافت کند. queryParameters اختیاری است. اگر تعریف شود تعدادی کوئری استرینگ دلخواه را میتواند به متد Uploader ارسال کند. برای نمونه در اینجا User و Id ارسال شدهاند یا هر نوع کوئری استرینگ دیگری که مدنظر است.
flashUrl مسیر فایل SWF را مشخص میکند. در اینجا فایل FlashFileUpload.swfدر پوشه Content/FlashUpload قرار گرفته است.
fileTypeDescription برچسبی است که نوع فایلهای قابل انتخاب را به کاربر نمایش میدهد و fileTypes نوعهای مجاز قابل ارسال را دقیقا مشخص میکند.
پارامترهای uploadFileSizeLimit و totalUploadSizeLimit در صورتیکه مساوی صفر وارد شوند، به معنای عدم محدودیت اندازه در فایلها و جمع حجم ارسالی در هر بار است.
استفاده از پارامتر onUploadComplete اختیاری است. در اینجا میتوان پس از پایان عملیات از طریق جاوا اسکریپت عملیاتی را انجام داد. برای مثال اگر خواستید کاربر را به صفحه خاصی هدایت کنید، window.locationرا مقدار دهی نمائید.
در متد Uploader کنترلر فوق، پارامترهای User و id اختیاری بوده و بر اساس queryParameters متد FlashUploadHelper.AddFlashUploader مشخص میشوند. اما نام FileData نباید تغییری کند؛ از این لحاظ که دقیقا همین نام در فایل فلش، مورد استفاده قرار گرفته است.
در اکشن متد دریافت فایلها، لیستی از فایلهای ارسالی به سرور دریافت شده و سپس بر این اساس میتوان آنها را در مکانی مشخص ذخیره نمود.
دریافت پروژه
MvcFlashUploader.zip