Разделы презентаций


MVC!!!

Содержание

Начало = проблема ?

Слайды и текст этой презентации

Слайд 1MVC!!!
Проектирование проекта

MVC!!! Проектирование проекта

Слайд 2Начало = проблема ?

Начало = проблема ?

Слайд 3Проблемы организации проекта

Слишком много проектов
Слишком мало проектов
Неверная абстракция

Проблемы организации проектаСлишком много проектовСлишком мало проектов Неверная абстракция

Слайд 4S
Single responsibility principle
Принцип единственной обязанности
На каждый класс должна быть возложена

одна-единственная обязанность.
O
Open/closed principle
Принцип открытости/закрытости
Программные сущности должны быть открыты для расширения,

но закрыты для изменения.
L
Liskov substitution principle
Принцип подстановки Барбары Лисков
Функции, которые используют базовый тип, должны иметь возможность использовать подтипы базового типа, не зная об этом.
I
Interface segregation principle
Принцип разделения интерфейса
Много специализированных интерфейсов лучше, чем один универсальный.
D
Dependency inversion principle
Принцип инверсии зависимостей
Зависимости внутри системы строятся на основе абстракций. Модули верхнего уровня не зависят от модулей нижнего уровня. Абстракции не должны зависеть от деталей. Детали должны зависеть от абстракций

SSingle responsibility principleПринцип единственной обязанностиНа каждый класс должна быть возложена одна-единственная обязанность.OOpen/closed principleПринцип открытости/закрытостиПрограммные сущности должны быть

Слайд 5Общие принципы

Принцип локализации изменений (common closure principle)
Общий принцип повторного использования

(common reuse principle)
Принцип стабильности зависимостей(stable dependencies)
Принцип стабильности абстракции
Разделение ответственности (separation

of concerns)
Принцип инверсии зависимостей (Dependency Inversion Principle, DIP)

SOLID(Или нафиг ? :) )
Общие принципыПринцип локализации изменений (common closure principle)Общий принцип повторного использования (common reuse principle)Принцип стабильности зависимостей(stable dependencies)Принцип стабильности

Слайд 6Локализация изменений

Классы которые меняются вместе - хранятся вместе

Локализация измененийКлассы которые меняются вместе - хранятся вместе

Слайд 7Принцип повторного использования

Компоненты которые используются вместе
- хранятся вместе.

Компоненты которые

НЕ используются вместе , не
должны храниться вместе.

Принцип повторного использованияКомпоненты которые используются вместе - хранятся вместе.Компоненты которые НЕ используются вместе , не должны храниться

Слайд 8Стабильность зависимостей

Граф зависимостей БЕЗ циклов
Пакет должен зависеть только от пакетов,

более стабильных, чем он сам

нестабильность пакета - мера вероятности появления

в нем изменений вследствие изменений других пакетов.

Стабильность зависимостейГраф зависимостей БЕЗ цикловПакет должен зависеть только от пакетов, более стабильных, чем он самнестабильность пакета -

Слайд 9Принцип стабильности абстракции







бесполезный

абстракция
стабильность
не гибкий

Принцип стабильности абстракциибесполезныйабстракциястабильностьне гибкий

Слайд 10Разделение ответственностей


как можно меньше перекрывающие функции

Разделение ответственностей как можно меньше перекрывающие функции

Слайд 11Принцип инверсии зависимостей

Абстракции не должны зависеть от

деталей. Детали должны зависеть от абстракций.

Нарушаем СОЛИД

%)

Принцип инверсии зависимостей   Абстракции не должны зависеть от деталей. Детали должны зависеть от абстракций.

Слайд 12Узнали принципы. И ?

Узнали принципы. И ?

Слайд 13N-layered архитектура

N-layered архитектура

Слайд 14каждый слой занимается конкретной задачей.
логика разных слоёв не повторяется и

не пересекается
способ обращения к нижестоящему слою чётко определён
способ поставки информации

вышестоящему слою чётко определён
слои расположены вертикально, хотя есть сквозная функциональность, которая может пронизывать пирамиду сверху вниз
слои могут размещаться физически на одном компьютере ( в пределах одного уровня), а могут быть на разных машинах, например, в распределённых приложениях.
логика разных слоёв инкапсулирована, соответственно, разным слоям не нужно делать никаких предположений о том, как реализован код других слоёв приложения.
возможность использования в других сценариях (за счёт слабого связывания и чётко определённой задачи).

Правила

каждый слой занимается конкретной задачей.логика разных слоёв не повторяется и не пересекаетсяспособ обращения к нижестоящему слою чётко

Слайд 15У нас 90% используют многослойную архитектуру ?


У нас 90% используют многослойную архитектуру ?

Слайд 16Разработка ведется снизу вверх (недостаток ??!?!?)
Изменения “снизу” могу вызывать проблемы

наверху
Разработчики часто путаются в какой из слоев запрограммировать (запихать)

новый код: DAL, BLL ?
Разработчик часто смотрит на архитектуру БД. Или это не недостаток ?
Мб кто еще подскажет ?)

Недостатки

Разработка ведется снизу вверх (недостаток ??!?!?)Изменения “снизу” могу вызывать проблемы наверху Разработчики часто путаются в какой из

Слайд 17Луковая архитектура

Луковая архитектура

Слайд 18Рассмотрим пример. Проект на mvc 5

Рассмотрим пример. Проект на mvc 5

Слайд 19Теперь добавим в решение (не в проект) новую папку. Назовем

ее Domain. Затем добавим в папку новый проект. В качестве

типа проекта выберем тип Class Library, а в качестве его названия укажем OnionApp.Domain.Core:
и добавим сюда класс:

namespace OnionApp.Domain.Core
{
public class Book
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
}
}

Теперь добавим в решение (не в проект) новую папку. Назовем ее Domain. Затем добавим в папку новый

Слайд 20Затем добавим в папку Domain новый проект также по типу

Class Library, а в качестве его названия укажем OnionApp.Domain.Interfaces. Затем

добавим в этот проект ссылку на вышеопределенный проект OnionApp.Domain.Core и также добавим новый интерфейса:


using System;
using System.Collections.Generic;
using OnionApp.Domain.Core;

namespace OnionApp.Domain.Interfaces
{
public interface IBookRepository: IDisposable
{
IEnumerable GetBookList();
Book GetBook(int id);
void Create(Book item);
void Update(Book item);
void Delete(int id);
void Save();
}
}

Затем добавим в папку Domain новый проект также по типу Class Library, а в качестве его названия

Слайд 21 Очередь за уровнем Domain Services , добавим в этот

проект интерфейс IOrder:

using OnionApp.Domain.Core;
namespace OnionApp.Services.Interfaces
{
public interface IOrder

{
void MakeOrder(Book book);
}
}

Очередь за уровнем Domain Services , добавим в этот проект интерфейс IOrder:using OnionApp.Domain.Core;namespace OnionApp.Services.Interfaces{  public

Слайд 22Теперь перейдем к созданию внешнего уровня, который и будет реализовывать

данные интерфейсы. Для этого добавим в решение папку Infrastructure и

затем в нее добавим новый проект по типу Class Library, который назовем OnionApp.Infrastructure.Data.

using System;
using System.Collections.Generic;
using System.Data.Entity;
using OnionApp.Domain.Core;

namespace OnionApp.Infrastructure.Data
{
public class OrderContext : DbContext
{
public DbSet Books { get; set; }
}
}

using System;
using System.Collections.Generic;
using System.Linq;
using OnionApp.Domain.Core;
using OnionApp.Domain.Interfaces;
using System.Data.Entity;

namespace OnionApp.Infrastructure.Data
{
public class BookRepository : IBookRepository
{
private OrderContext db;

public BookRepository()
{
this.db = new OrderContext();
}

public IEnumerable GetBookList()
{
return db.Books.ToList();
}

Теперь перейдем к созданию внешнего уровня, который и будет реализовывать данные интерфейсы. Для этого добавим в решение

Слайд 23Получим


Получим

Слайд 24Тоже самое для IOrder.
using OnionApp.Domain.Core;
using OnionApp.Services.Interfaces;

namespace OnionApp.Infrastructure.Business
{
public

class CacheOrder : IOrder
{
public

void MakeOrder(Book book)
{
// код покупки книги при оплате наличностью
}
}
}
using OnionApp.Domain.Core;
using OnionApp.Services.Interfaces;

namespace OnionApp.Infrastructure.Business
{
public class CreditOrder : IOrder
{
public void MakeOrder(Book book)
{
// код покупки книги с помощью кредитной карты
}
}
}


Тоже самое для IOrder.using OnionApp.Domain.Core;using OnionApp.Services.Interfaces; namespace OnionApp.Infrastructure.Business{  public class CacheOrder : IOrder  {

Слайд 25using OnionApp.Domain.Core;
using OnionApp.Domain.Interfaces;
using OnionApp.Services.Interfaces;

namespace OnionApp.Controllers
{
public class HomeController

: Controller
{
IBookRepository repo;

IOrder order;
public HomeController(IBookRepository r, IOrder o)
{
repo = r;
order = o;
}
public ActionResult Index()
{
var books = repo.GetBookList();
return View();
}

public ActionResult Buy(int id)
{
Book book = repo.GetBook(id);
order.MakeOrder(book);
return View();
}
using OnionApp.Domain.Core;using OnionApp.Domain.Interfaces;using OnionApp.Services.Interfaces; namespace OnionApp.Controllers{  public class HomeController : Controller  {

Слайд 26namespace OnionApp.Util
{
public class NinjectDependencyResolver : IDependencyResolver
{

private IKernel kernel;
public

NinjectDependencyResolver(IKernel kernelParam)
{
kernel = kernelParam;
AddBindings();
}
public object GetService(Type serviceType)
{
return kernel.TryGet(serviceType);
}
public IEnumerable GetServices(Type serviceType)
{
return kernel.GetAll(serviceType);
}
private void AddBindings()
{
kernel.Bind().To();
kernel.Bind().To();
}
}
}

namespace OnionApp.Util{  public class NinjectDependencyResolver : IDependencyResolver  {    private IKernel kernel;

Слайд 29Паттерн Unit of Work
SQL Транзакции -> Бизнес транзакции


Паттерн Unit of WorkSQL Транзакции -> Бизнес транзакции

Слайд 30public class Book
{
public int Id { get; set;

}
public string Name { get; set; }

public decimal Price { get; set; }
}

public class Order
{
public int Id { get; set; }
public string Number { get; set; }
public int BookId { get; set; }
public Book Book { get; set; }
}



public class OrderContext : DbContext
{
public DbSet Books { get; set; }
public DbSet Orders { get; set; }
}

public class Book{  public int Id { get; set; }  public string Name { get;

Слайд 31interface IRepository where T : class
{
IEnumerable GetAll();

T Get(int id);
void Create(T item);
void Update(T

item);
void Delete(int id);
}

public class BookRepository : IRepository
{
private OrderContext db;

public BookRepository(OrderContext context)
{
this.db = context;
}

public IEnumerable GetAll()
{
return db.Books;
}

public Book Get(int id)
{
return db.Books.Find(id);
}



public class OrderRepository : IRepository
{
private OrderContext db;

public OrderRepository(OrderContext context)
{
this.db = context;
}

public IEnumerable GetAll()
{
return db.Orders.Include(o=>o.Book);
}

public Order Get(int id)
{
return db.Orders.Find(id);
}

public void Create(Order order)
{
db.Orders.Add(order);
}


interface IRepository where T : class{  IEnumerable GetAll();  T Get(int id);  void Create(T item);

Слайд 32public class UnitOfWork : IDisposable
{
private OrderContext db =

new OrderContext();
private BookRepository bookRepository;
private OrderRepository orderRepository;


public BookRepository Books
{
get
{
if (bookRepository == null)
bookRepository = new BookRepository(db);
return bookRepository;
}
}

public OrderRepository Orders
{
get
{
if (orderRepository == null)
orderRepository = new OrderRepository(db);
return orderRepository;
}
}


public void Save()
{
db.SaveChanges();
}

private bool disposed = false;

public virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
db.Dispose();
}
}
this.disposed = true;
}

public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}


public class UnitOfWork : IDisposable{  private OrderContext db = new OrderContext();  private BookRepository bookRepository;

Слайд 33using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using UoWMvcApp.Models;

namespace UoWMvcApp.Controllers
{

public class HomeController : Controller
{

UnitOfWork unitOfWork;
public HomeController()
{
unitOfWork = new UnitOfWork();
}
public ActionResult Index()
{
var books = unitOfWork.Books.GetAll();
return View();
}

public ActionResult Create()
{
return View();
}


[HttpPost]
public ActionResult Create(Book b)
{
if(ModelState.IsValid)
{
unitOfWork.Books.Create(b);
unitOfWork.Save();
return RedirectToAction("Index");
}
return View(b);
}

public ActionResult Edit(int id)
{
Book b = unitOfWork.Books.Get(id);
if (b == null)
return HttpNotFound();
return View(b);
}

[HttpPost]
public ActionResult Edit(Book b)
{
if (ModelState.IsValid)
{
unitOfWork.Books.Update(b);
unitOfWork.Save();
return RedirectToAction("Index");

using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.Mvc;using UoWMvcApp.Models; namespace UoWMvcApp.Controllers{  public class HomeController : Controller  {

Слайд 34Unit of Work For ADO.NET
using (TransactionScope _scope = new TransactionScope())

{
using (SqlConnection _con = new SqlConnection(_connectionString))
{

Бизнес транзакции

}
_scope.Complete();
}

Unit of Work For ADO.NETusing (TransactionScope _scope = new TransactionScope()) {  using (SqlConnection _con = new

Слайд 35AUTOMAPPER

AUTOMAPPER

Слайд 36public class User
{
public int Id { get; set;

}
public string Name { get; set; }

public int Age { get; set; }
public string Email { get; set; }
}

public class IndexUserViewModel
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}
public class CreateUserViewModel
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
public string Login { get; set; }
}

// Настройка AutoMapper
Mapper.CreateMap();
// сопоставление
var users = Mapper.Map,
List>(repo.GetAll());


Mapper.CreateMap()
.ForMember("Name", opt => opt.MapFrom(c => c.FirstName + " " + c.LastName))
.ForMember("Email", opt => opt.MapFrom(src => src.Login));


Слайд 37Немного “точечных” советов

Немного “точечных” советов

Слайд 38Отключите неиспользуемые движки представлений
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new RazorViewEngine());

Избегайте передачи в представления null вместо

модели
Html.TextBoxFor(model => model.Name) - БДЫЩЬ!!!!
public ActionResult Insert()
{

// return View(); <-- вот этот код передал бы null в качестве модели
return View(new Product());
}

Отключите неиспользуемые движки представленийViewEngines.Engines.Clear();ViewEngines.Engines.Add(new RazorViewEngine());Избегайте передачи в представления null вместо моделиHtml.TextBoxFor(model => model.Name) - БДЫЩЬ!!!! public ActionResult

Слайд 39Сделать сессию ReadOnly или выключить вообще. Отменяет блокировки обработчиков запросов.


















Сделать сессию ReadOnly или выключить вообще. Отменяет блокировки обработчиков запросов.

Слайд 40Выкладываемся в режиме RELEASE!!!
:)

Кэшируем конроллеры
[OutputCache(Duration=10, VaryByParam="none")]
Используем “тупые” view
Если else,

то htmlhelper
Максимально используем чистый html в view



Выкладываемся в режиме RELEASE!!! :)Кэшируем конроллеры[OutputCache(Duration=10, VaryByParam=

Слайд 41Используйте Async- контроллеры

namespace AsyncContollers.Controllers
{
public class HomeController : Controller

{
BookContext db = new BookContext();

// синхронный
public ActionResult Index()
{
IEnumerable books = db.Books;
ViewBag.Books = books;
return View();
}

// асинхронный метод
public async Task BookList()
{
IEnumerable books = await Task.Run(() => db.Books);
ViewBag.Books = books;
return View("Index");
}
}
}



Используйте Async- контроллерыnamespace AsyncContollers.Controllers{  public class HomeController : Controller  {    BookContext db

Обратная связь

Если не удалось найти и скачать доклад-презентацию, Вы можете заказать его на нашем сайте. Мы постараемся найти нужный Вам материал и отправим по электронной почте. Не стесняйтесь обращаться к нам, если у вас возникли вопросы или пожелания:

Email: Нажмите что бы посмотреть 

Что такое TheSlide.ru?

Это сайт презентации, докладов, проектов в PowerPoint. Здесь удобно  хранить и делиться своими презентациями с другими пользователями.


Для правообладателей

Яндекс.Метрика