• 学习ASP.NET MVC5的一个轻量级的NinJect框架学习的第二天


      新建一个Abstract文件夹   放置一些抽象的类,如接口
      我们通过该接口就可以得到对应类的相关信息, 不需要去管该数据如何存储,以及存储的位置,这就是存储库模式的本质
     public  interface IbookRepository
        {    /// <summary>
             /// 书模型集合
             /// </summary>
            /*我们通过该接口就可以得到对应类的相关信息,
            而不需要去管该数据如何存储,以及存储的位置,这就是存储库模式的本质。*/
            IQueryable<Book> Books { get; }
        }
      

    新建一个Concrete文件夹新建一个EfDbContext类,他派生与Dbcontext,他会为数据库中的每一个表定义一个属性(这里是Books)

    DbSet<Book>为Book的实体模型
        /// <summary>
        /// 书的上下文对象
        /// </summary>
       public   class EfDbContext: DbContext
        {
          public DbSet<Book> Books { get; set; }
        }

    再创建EfBookRepository存储类库,它实现 IBookRepository 接口,使用了上文创建的 EfDbContext 上下文对象,包含了具体的方法定义

      public class EfIBookRepository :IbookRepository
        {
            private readonly EfDbContext _context = new EfDbContext();

            public IQueryable<Book> Books => _context.Books;
          
        }

    再接下来创建一个Entities文件夹


    //为Book添加一个特性

     [Table("Book")]
        public class Book
        {
            /// <summary>
            /// 标识
            /// </summary>
            public int Id { get; set; }

            /// <summary>
            /// 名称
            /// </summary>

            public string Name { get; set; }

            /// <summary>
            /// 描述
            /// </summary>
        
            public string Description { get; set; }

            /// <summary>
            /// 价格
            /// </summary>
         
            public decimal Price { get; set; }

            /// <summary>
            /// 分类
            /// </summary>
       
            public string Category { get; set; }
        }

    再回到WebUI

    新建一个文件夹存放我们自定义的工厂  新建一个NinjectControllerFactory 的类 他继承了DefaultControllerFactory这个控制器工厂的类

    在这里面也可以添加自定义的代码,可以改变MVC的默认行为

     public class NinjectControllerFactory: DefaultControllerFactory
        {
            private readonly IKernel _kernel;
            public NinjectControllerFactory()
            {
                _kernel = new StandardKernel();
                AddBindings();
            }
            protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
            {
                return controllerType == null
                   ? null
                   : (IController)_kernel.Get(controllerType);
            }
            /// <summary>
            /// 添加绑定
            /// 因为我们使用了 Ninject 容器,并且需要对控制器中的构造函数中的参数 IBookRepository 进行解析,
            /// 告诉他将使用哪个对象对该接口进行服务,也就是需要修改之前的 AddBindings 方法
            /// </summary>
            private void AddBindings()
            {

           //这里注意 每添加一个接口这里就要进行绑定  上面是解释
                _kernel.Bind<IbookRepository>().To<EfIBookRepository>();
               // _kernel.Bind<IOrderProcessor>().To<EmailOrderProcessor>();

            }

    在这里还要在Global.asax里添加一段代码,告诉 MVC 用新建的类来创建控制器对象


            protected void Application_Start()
            {
                AreaRegistration.RegisterAllAreas();
                RouteConfig.RegisterRoutes(RouteTable.Routes);

       ///ControllerBuilder这个类动态的生成一个控制器,设置指定的控制器工厂
                ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory());
            }

    现在要为项目添加控制器,视图了

    public class BookController : Controller
        {
            private readonly IbookRepository _bookRepository;
            
            public int PageSize = 5;
            public BookController(IbookRepository bookRepository)
            {
                _bookRepository = bookRepository;
            }
               /// <summary>
               /// 首页显示全部书的信息,并分页
               /// </summary>
               /// <param name="category"></param>
               /// <param name="pageIndex"></param>
               /// <returns></returns>
            public ActionResult Details(string category, int pageIndex = 1)
            {
                var model = new BookDetailsViewModels
                {
                    Books =
                        _bookRepository.Books.Where(x => category == null || x.Category == category)
                            .OrderBy(x => x.Id)
                            .Skip((pageIndex - 1) * PageSize)
                            .Take(PageSize),
                    CurrentCategory = category,
                    PageSize = PageSize,
                    PageIndex = pageIndex,
                    TotalItems = _bookRepository.Books.Count(x => category == null || x.Category == category)
                };
                return View(model);
            }
        }

    @model Wen.BooksStore.WebUI.Models.BookDetailsViewModels

    @{
        ViewBag.Title = "Books";
    }

    <!DOCTYPE html>

    @foreach (var item in Model.Books)
    {
        Html.RenderPartial("_BookSummary", item);
    }
        <div class="pager">
            @Html.PageLinks(Model, x => Url.Action("Details", new { pageIndex = x, category = Model.CurrentCategory }))
        </div>


    现在基本可以显示了   接下来就是配置伟大的路由了

      public static void RegisterRoutes(RouteCollection routes)
            {
                routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

                routes.MapRoute(
                  name: "Default",
                  url: "{controller}/{action}",
                  defaults: new { controller = "Book", action = "Details" }
              );
                routes.MapRoute(
                 name: null,
                 url: "{controller}/{action}/{category}",
                 defaults: new { controller = "Book", action = "Details" }
             );

                routes.MapRoute(
                    name: null,
                    url: "{controller}/{action}/{category}/{pageIndex}",
                    defaults: new { controller = "Book", action = "Details", pageIndex = UrlParameter.Optional }
                );
            }

    现在可以显示了 那我就接下来做一个购物车实现购买吧

    在Abstract文件夹先添加IOrderProcessor接口

       public interface IOrderProcessor
        {/// <summary>
         /// 处理订单
         /// </summary>
         /// <param name="cart"></param>
         /// <param name="contact"></param>
            void ProcessOrder(Cart cart,Contact contact);
          
        }

    并在Concrete文件夹下添加EmailOrderProcessor类并继承IOrderProcessor

     /// <summary>
            /// 处理订单
            /// </summary>
            /// <param name="cart"></param>
            /// <param name="contact"></param>
            public void ProcessOrder(Cart cart, Contact contact)
            {
                if (string.IsNullOrEmpty(contact.Email))
                {
                    throw new Exception("Email 不能为空!");
                }

                var sb = new StringBuilder();
                foreach (var item in cart.GetCarItems)
                {
                    sb.AppendLine($"《{item.Book.Name}》:{item.Book.Price} * {item.Quantity} = {item.Book.Price * item.Quantity}");
                }

                sb.AppendLine($"总额:{cart.GetCarItems.Sum(x => x.Quantity * x.Book.Price)}");
                sb.AppendLine();
                sb.AppendLine($"联系人:{contact.Name} {contact.Address}");

                //设置发件人,发件人需要与设置的邮件发送服务器的邮箱一致
                var fromAddr = new MailAddress(Sender.Account);
                var message = new MailMessage { From = fromAddr };

                //设置收件人,可添加多个,添加方法与下面的一样
                message.To.Add(contact.Email);
                //设置抄送人
                message.CC.Add(Sender.Account);
                //设置邮件标题
                message.Subject = "您的订单正在出库...";
                //设置邮件内容
                message.Body = sb.ToString();
                //设置邮件发送服务器,服务器根据你使用的邮箱而不同,可以到相应的 邮箱管理后台查看,下面是QQ的

                var client = new SmtpClient("smtp.qq.com", 25)
                {
                    Credentials = new NetworkCredential(Sender.Account, Sender.Password),
                    EnableSsl = true
                };

                //设置发送人的邮箱账号和密码
                //启用ssl,也就是安全发送
                //发送邮件
                client.Send(message);
            }

    接下来在Entitites文件夹下添加Cart购物车实体模型

       
        public   class Cart
        {
            private readonly List<CartItem> _cartitems = new List<CartItem>();
            public IList<CartItem> GetCarItems => _cartitems;

            /// <summary>
            /// 添加书的模型
            /// </summary>
            /// <param name="book"></param>
            /// <param name="quantity"></param>
            public void AddBook(Book book,int quantity)
            {
                if (_cartitems.Count==0)
                {
                    _cartitems.Add(new CartItem() { Book = book, Quantity = quantity });
                    return;
                }
                var model = _cartitems.FirstOrDefault(x=>x.Book.Id==book.Id);
                if (model==null)
                {
                    _cartitems.Add(new CartItem() {Book=book,Quantity=quantity });
                    return;
                }
                model.Quantity += quantity;
            }
            /// <summary>   
            /// 移除书的模型
            /// </summary>
            /// <param name="book"></param>
            public void RemoveBook(Book book)
            {
                var model = _cartitems.FirstOrDefault(x=>x.Book.Id==book.Id);
                if (model==null)
                {
                    return;
                }
                _cartitems.RemoveAll(x=>x.Book.Id==book.Id);
            }
            /// <summary>
            /// 清空购物车
            /// </summary>
            public void Clear()
            {
                _cartitems.Clear();
            }
            /// <summary>
            /// 统计总额
            /// </summary>
            /// <returns></returns>
            public decimal ComputeTotalValue()
            {
                return _cartitems.Sum(x => x.Book.Price * x.Quantity);
            }
        }

    再添加一个购物车项存放添加的书并显示用户添加的

     public   class CartItem
        {
            /// <summary>
            /// 书-+--
            /// </summary>
           public Book Book { get; set; }
            /// <summary>
            /// 数量
            /// </summary>
            public int Quantity { get; set; }
        }

    一切都完
    现在做添加到购物车吧

     public class CartController : Controller
        {
            private readonly IbookRepository _bookRepository;
            private readonly IOrderProcessor _orderprocessor;
            public CartController(IbookRepository bookRepository,IOrderProcessor orderprocessor)
            {
                _bookRepository = bookRepository;
                _orderprocessor = orderprocessor;

            }
            /// <summary>
            /// 首页
            /// </summary>
            /// <returns></returns>
            public ViewResult Index(string returnUrl)
            {
                return View(new CartViewModels() {

                    Cart = GetCart(),
                    ReturnUrl=returnUrl


                });
            }
            /// <summary>
            /// 添加到购物车
            /// </summary>
            /// <param name="id"></param>
            /// <param name="returnUrl"></param>
            /// <returns></returns>
            public RedirectToRouteResult AddToCart(int id, string returnUrl)
            {
                var book = _bookRepository.Books.FirstOrDefault(x => x.Id == id);

                if (book != null)
                {
                    GetCart().AddBook(book, 1);
                }

                return RedirectToAction("Index", new { returnUrl });
            }
            /// <summary>
            /// 移除书的模型
            /// </summary>
            /// <param name="id"></param>
            /// <param name="returnUrl"></param>
            /// <returns></returns>
            public RedirectToRouteResult RemoveFromCart(int id,string returnUrl)
            {
                var book = _bookRepository.Books.FirstOrDefault(x => x.Id == id);

                if (book != null)
                {
                    GetCart().RemoveBook(book);
                }
                return RedirectToAction("Index", new {returnUrl });
            }

            /// <summary>
            /// 获取购物车
            /// </summary>
            /// <returns></returns>

            private Cart GetCart()
            {
                var cart = (Cart)Session["Cart"];
                if (cart != null) return cart;
                cart = new Cart();
                Session["Cart"] = cart;
                return cart;
            }
            /// <summary>
            /// 摘要
            /// </summary>
            /// <returns></returns>
            public PartialViewResult Summary()
            {
                return PartialView(GetCart());
            }

            /// <summary>
            /// 结算
            /// </summary>
            /// <returns></returns>
            public ViewResult Checkout()
            {
                return View(new Contact());
            }

            /// <summary>
            /// 结算
            /// </summary>
            /// <param name="contact"></param>
            /// <returns></returns>
            [HttpPost]
            public ViewResult Checkout(Contact contact)
            {
                if (!ModelState.IsValid)
                    return View(contact);

                var cart = GetCart();
                _orderprocessor.ProcessOrder(cart, contact);
                cart.Clear();
                return View("Thanks");
            }
            /// <summary>
            /// 清空购物车
            /// </summary>
            /// <param name="id"></param>
            /// <param name="returnUrl"></param>
            /// <returns></returns>
            public RedirectToRouteResult Clear(string returnUrl)
            {
                GetCart().Clear();
                return RedirectToAction("Index",new {returnUrl });
            }
        }

    这里注意的是只添加一个视图就是Index

    其他三个页面都添加

     再新建一个视图文件夹Shared

    _Layout页面

    <!DOCTYPE html>

    <html>
    <head>
        <meta name="viewport" content="width=device-width" />
        <title>@ViewBag.Title</title>
        <link href="~/Contents/Site.css" rel="stylesheet" />
        <script src="~/Scripts/jquery-1.10.2.js"></script>
        <script src="~/Scripts/jquery.validate.js"></script>
        <script src="~/Scripts/jquery.validate.unobtrusive.js"></script>
    </head>
    <body>
        <div id="header">
            @{ Html.RenderAction("Summary", "Cart");}
            <div class="title">图书商城</div>
        </div>
            <div id="sideBar">
                @{ Html.RenderAction("Sidebar", "Nav"); }
            </div>
            <div>
                @RenderBody()
            </div>
    </body>
    </html>


    _BookSummary页面

    @model Wen.BooksStore.Domain.Entitites.Book


    <div class="item">
        <h3>@Model.Name</h3>
        @Model.Description
        <h4>@Model.Price.ToString("C")</h4>
        @using (Html.BeginForm("AddToCart", "Cart"))
        {
            var id = Model.Id;
            @Html.HiddenFor(x => id);
            @Html.Hidden("returnUrl", Request.Url.PathAndQuery)

            <input type="submit" value="+ 添加到购物车" />
        }
        <br />
        <hr />
    </div>
     最后在Views文件夹下添加_ViewStart页面

    @{
        Layout = "~/Views/Shared/_Layout.cshtml";
    }
    补充一个  书的分类  创建Nav控制器
      public class NavController : Controller
        {
            private readonly IbookRepository _bookRepository;
            public NavController(IbookRepository bookRepository)
            {
                _bookRepository = bookRepository;
            }
            // GET: Nav
     
            public PartialViewResult Sidebar(string category= null)
            {
                ViewBag.CurrentCategory = category;
                var categories = _bookRepository.Books.Select(x=>x.Category).Distinct().OrderBy(x=>x);
                return PartialView(categories);

            }

    @model IEnumerable<string>
     

    <ul>
        <li>@Html.ActionLink("所有分类","Details","Book")</li>
        @foreach (var item in Model)
        {
            <li>@Html.RouteLink(item, new { controller = "Book", action = "Details", category = item, pageIndex = 1 }, new { @class = item == ViewBag.CurrentCategory ? "selected" : null })</li>

        }
    </ul>



        }
    最后还有一个重大事,就是整个的样式  在WebUI下新建一个文件夹  Contents  新建一个样式Site

    body {
    }

    #header, #content, #sideBar {
        display: block;
    }

    #header {
        background-color: green;
        border-bottom: 2px solid #111;
        color: White;
    }

    #header, .title {
        font-size: 1.5em;
        padding: .5em;
    }

    #sideBar {
        float: left;
        8em;
        padding: .3em;
    }

    #content {
        border-left: 2px solid gray;
        margin-left: 10em;
        padding: 1em;
    }

    .pager {
        text-align: right;
        padding: .5em 0 0 0;
        margin-top: 1em;
    }

        .pager A {
            font-size: 1.1em;
            color: #666;
            padding: 0 .4em 0 .4em;
        }

            .pager A:hover {
                background-color: Silver;
            }

            .pager A.selected {
                background-color: #353535;
                color: White;
            }

    .item input {
        float: right;
        color: White;
        background-color: green;
    }

    .table {
        100%;
        padding: 0;
        margin: 0;
    }

        .table th {
            font: bold 12px "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif;
            color: #4f6b72;
            border-right: 1px solid #C1DAD7;
            border-bottom: 1px solid #C1DAD7;
            border-top: 1px solid #C1DAD7;
            letter-spacing: 2px;
            text-transform: uppercase;
            text-align: left;
            padding: 6px 6px 6px 12px;
            background: #CAE8EA no-repeat;
        }

        .table td {
            border-right: 1px solid #C1DAD7;
            border-bottom: 1px solid #C1DAD7;
            background: #fff;
            font-size: 14px;
            padding: 6px 6px 6px 12px;
            color: #4f6b72;
        }

            .table td.alt {
                background: #F5FAFA;
                color: #797268;
            }

        .table th.spec, td.spec {
            border-left: 1px solid #C1DAD7;
        }

    .bookSummary {
        15%;
        float: right;
        margin-top: 1.5%;
    }

    .error {
        color: red;
    }

    最后大搞成了

    最后总结一下,Ninject是一个IOC容器用来解决程序中组件的耦合问题,它的目的在于做到最少配置。

    其他的的IOC工具过于依赖配置文件,需要使用assembly-qualified名称来进行定义,庸长且复杂常常因为打错字而破坏程序,虽然不是很懂,

    但是我会一直继续摸索下去



  • 相关阅读:
    python接口自动化-json数据处理
    Fiddler-抓取手机app请求
    monkey常用命令实例
    python接口自动化-Cookie_绕过验证码登录
    python接口自动化-session_自动发文
    python接口自动化-post请求4
    python接口自动化-post请求3
    Python学习笔记第十五周
    Python学习笔记第十四周
    Python学习笔记第十二周
  • 原文地址:https://www.cnblogs.com/pang572936554/p/6759495.html
Copyright © 2020-2023  润新知