Listing 3-1. The C# Auction Domain Model

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web; namespace MvcPattern.Models
{
public class Member
{
public string LoginName { get; set; } // The unique key
public int ReputationPoints { get; set; }
} public class Bid
{
public Member Member { get; set; }
public DateTime DatePlaced { get; set; }
public decimal BidAmount { get; set; }
} public class Item
{
public int ItemID { get; private set; } // The unique key
public string Title { get; set; }
public string Description { get; set; }
public DateTime AuctionEndDate { get; set; }
public IList<Bid> Bids { get; set; }
}
}

Listing 3-2. C# Repository Classes for the Member and Item Domain Classes

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web; namespace MvcPattern.Models
{
public class MembersRepository
{
public void AddMember(Member member)
{ } public Member FetchByLoginName(string loginName)
{
return null;
} public void SubmitChanges()
{ }
} public class ItemsRepository
{
public void AddItem(Item item)
{ } public Item FetchById(int itemId)
{
return null;
} public IList<Item> ListItems(int pageSize, int pageIndex)
{
return null;
} public void SubmitChanges()
{ }
}
}

Listing 3-3. Instantiating Concrete Classes to Get an Interface Implementation

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web; namespace MvcPattern.Models
{
public class PasswordResetHelper
{
public void ResetPassword()
{
IEmailSender mySender = new MyEmailSender(); // Call interface methods to configure e-mail details mySender.SendEmail();
}
}
} using System;
using System.Collections.Generic;
using System.Linq;
using System.Web; namespace MvcPattern.Models
{
public interface IEmailSender
{
void SendEmail();
} public class MyEmailSender : IEmailSender
{
public void SendEmail()
{
}
}
}

Listing 3-4. Removing Dependencies from the PasswordResetHelper Class

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web; namespace MvcPattern.Models
{
public class PasswordResetHelper
{
private IEmailSender _emailSender; public PasswordResetHelper(IEmailSender emailSender)
{
_emailSender = emailSender;
} public void ResetPassword()
{
// Call interface methods to configure e-mail details
_emailSender.SendEmail();
}
}
}

Listing 3-5. The IMembersRepository Interface

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web; namespace MvcPattern.Models
{
public interface IMembersRepository
{
void AddMember(Member member);
Member FetchByLoginName(string loginName);
void SubmitChanges();
} public class MembersRepository : IMembersRepository
{
public void AddMember(Member member)
{ } public Member FetchByLoginName(string loginName)
{
return null;
} public void SubmitChanges()
{ }
}
}

Listing 3-6. The AdminController Class

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MvcPattern.Models; namespace MvcPattern.Controllers
{
public class AdminController : Controller
{
IMembersRepository _membersRepository; public AdminController(IMembersRepository membersRepository)
{
_membersRepository = membersRepository;
} public ActionResult ChangeLoginName(string oldLoginName, string newLoginName)
{
Member member = _membersRepository.FetchByLoginName(oldLoginName);
member.LoginName = newLoginName; _membersRepository.SubmitChanges(); return View();
}
}
}

Listing 3-7. An Example Test Fixture

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using MvcPattern.Controllers;
using MvcPattern.Models; namespace MvcPattern.Tests
{
[TestClass]
public class AdminControllerTest
{
[TestMethod]
public void CanChangeLoginName()
{
// Arrange (set up a scenario)
Member bob = new Member() { LoginName = "Bob" };
FakeMembersRepository repository = new FakeMembersRepository();
repository.Members.Add(bob); AdminController target = new AdminController(repository); string oldLoginName = bob.LoginName;
string newLoginName = "Anastasia"; // Act (attempt the operation)
target.ChangeLoginName(oldLoginName, newLoginName); // Assert (verify the result)
Assert.AreEqual(newLoginName, bob.LoginName);
Assert.IsTrue(repository.DidSubmitChanges); }
} private class FakeMembersRepository : IMembersRepository
{
public List<Member> Members = new List<Member>();
public bool DidSubmitChanges = false; public void AddMember(Member member)
{
} public Member FetchByLoginName(string loginName)
{
return Members.First(m => m.LoginName == loginName);
} public void SubmitChanges()
{
DidSubmitChanges = true;
}
}
}

Listing 3-8. Adding a Stub Method to the Item Class

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web; namespace MvcPattern.Models
{
public class Item
{
public int ItemID { get; private set; } // The unique key
public string Title { get; set; }
public string Description { get; set; }
public DateTime AuctionEndDate { get; set; }
public IList<Bid> Bids { get; set; } public void AddBid(Member member, Decimal amount)
{
throw new NotImplementedException();
}
}
}

Listing 3-9. Three Test Fixtures

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using MvcPattern.Controllers;
using MvcPattern.Models; namespace MvcPattern.Tests
{
[TestClass]
public class AdminControllerTest
{
[TestMethod]
public void CanAddBid()
{
// Arrange - set up the scenario
Item target = new Item();
Member member = new Member();
Decimal amount = 150M; // Act - perform the test
target.AddBid(member, amount); // Assert - check the behavior
Assert.AreEqual(, target.Bids.Count());
Assert.AreEqual(amount, target.Bids[].BidAmount);
} [TestMethod()]
[ExpectedException(typeof(InvalidOperationException))]
public void CannotAddLowerBid()
{
// Arrange
Item target = new Item();
Member member = new Member();
Decimal amountParam = 150M; // Act
target.AddBid(member, amountParam);
target.AddBid(member, amountParam - );
} [TestMethod()]
public void CanAddHigherBid()
{
// Arrange
Item target = new Item();
Member firstMember = new Member();
Member secondMember = new Member();
Decimal amount = 150M; // Act
target.AddBid(firstMember, amount);
target.AddBid(secondMember, amount + ); // Assert
Assert.AreEqual(, target.Bids.Count());
Assert.AreEqual(amount + , target.Bids[].BidAmount);
}
}
}

Listing 3-10. Implementing the AddBid Method

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web; namespace MvcPattern.Models
{
public class Item
{
public int ItemID { get; private set; } // The unique key
public string Title { get; set; }
public string Description { get; set; }
public DateTime AuctionEndDate { get; set; }
public IList<Bid> Bids { get; set; } public Item()
{
Bids = new List<Bid>();
} public void AddBid(Member member, Decimal amount)
{
Bids.Add(new Bid() {
BidAmount = amount,
DatePlaced = DateTime.Now,
Member = member
});
}
}
}

Listing 3-11. Improving the Implementation of the AddBid Method

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web; namespace MvcPattern.Models
{
public class Item
{
public int ItemID { get; private set; } // The unique key
public string Title { get; set; }
public string Description { get; set; }
public DateTime AuctionEndDate { get; set; }
public IList<Bid> Bids { get; set; } public Item()
{
Bids = new List<Bid>();
} public void AddBid(Member member, Decimal amount)
{
if (Bids.Count == || amount > Bids.Max(e => e.BidAmount))
{
Bids.Add(new Bid()
{
BidAmount = amount,
DatePlaced = DateTime.Now,
Member = member
});
}
else
{
throw new InvalidOperationException("Bid amount too low");
}
}
}
}

Pro Aspnet MVC 4读书笔记(2) - The MVC Pattern的更多相关文章

  1. 【Tools】Pro Git 一二章读书笔记

    记得知乎以前有个问题说:如果用一天的时间学习一门技能,选什么好?里面有个说学会Git是个很不错选择,今天就抽时间感受下Git的魅力吧.   Pro Git (Scott Chacon) 读书笔记:   ...

  2. [Git00] Pro Git 一二章读书笔记

    记得知乎以前有个问题说:如果用一天的时间学习一门技能,选什么好?里面有个说学会Git是个很不错选择,今天就抽时间感受下Git的魅力吧.   Pro Git (Scott Chacon) 读书笔记:   ...

  3. Pro Aspnet MVC 4读书笔记(1) - Your First MVC Application

    Listing 2-1. The default contents of the HomeController class using System; using System.Collections ...

  4. Pro Aspnet MVC 4读书笔记(4) - Working with Razor

    Listing 5-1. Creating a Simple Domain Model Class using System; using System.Collections.Generic; us ...

  5. Pro Aspnet MVC 4读书笔记(3) - Essential Language Features

    Listing 4-1. The Initial Content of the Home Controller using System; using System.Collections.Gener ...

  6. Pro Aspnet MVC 4读书笔记(5) - Essential Tools for MVC

    Listing 6-1. The Product Model Class using System; using System.Collections.Generic; using System.Li ...

  7. 《Pro Android Graphics》读书笔记之第四节

    Android Procedural Animation: : XML, Concepts and Optimization Procedural Animation Concepts: Tweens ...

  8. 《Pro Android Graphics》读书笔记之第三节

    Android Frame Animation: XML, Concepts and Optimization Frame Animation Concepts: Cels, Framerate, a ...

  9. 《Pro Android Graphics》读书笔记之第六节

    Android UI Layouts: Graphics Design Using the ViewGroup Class Android ViewGroup Superclass: A Founda ...

随机推荐

  1. 使用LabVIEWPC的制备

    使用LabVIEWPC的制备 1.下载.安装LabVIEW 如今,互联网搜索,你可以搜索出一大推LabVIEW下载并安装破解教程.因此,这里没有具体描述的.请自行百度~~.另外.提醒一下,下载LabV ...

  2. Android 通过系统使用NotificationListenerService 监听各种Notification的用法

    NotificationListenerService是通过系统调起的服务,当有应用发起通知的时候,系统会将通知的动作和信息回调给NotificationListenerService. 在继承Not ...

  3. SQLServer 网络协议(一)

    SQLserver现在主要的3种协议:Shared Memory.TCP/IP 和 Named Pipe SharedMemory: Shared Memory最快最简单的协议,使用SharedMem ...

  4. SharePoint 2010 新列表模板列表

    SharePoint 2010 新列表模板列表 项目描述叙事 发展环境创造了良好的名单为模板.然后使用列表模板将其复制到生产环境. 脚步 1. 打开"列表设置",找到"将 ...

  5. springmvc如何访问静态文件,例如jpg,js,css

    你怎么DispatcherServlet拦截"*.do"这有一个后缀URL.就不存在訪问不到静态资源的问题.   假设你的DispatcherServlet拦截"/&qu ...

  6. MVC与三层架构

    我们平时总是将三层架构与MVC混为一谈,殊不知它俩并不是一个概念.下面我来为大家揭晓我所知道的一些真相. 首先,它俩根本不是一个概念. 三层架构是一个分层式的软件体系架构设计,它可适用于任何一个项目. ...

  7. windows azure Vm、cloud service、web application 如何选择可用的服务

    windows azure 的web应用和虚拟机都经常用.我们经常把我们的网站部署上去.一般选择web应用或者开一个虚拟机.开一个虚拟机就会按照虚拟机的使用时间进行计费. 那么我们选择web部署在哪里 ...

  8. js多物体任意值运动

    假如有两个div,一个div要变宽,一个div要变高,你怎么写呢? 哎呀,写2个方法啊,一个控制div1变宽,一个控制div2变高啊 那么你的代码,是不是下面这样的呢! 示例:Div变宽和变高 现象: ...

  9. C# WinForm多线程(一)Thread类库

    Windows是一个多任务的系统,如果你使用的是windows 2000及其以上版本,你可以通过任务管理器查看当前系统运行的程序和进程.什么是进程呢?当一个程序开始运行时,它就是一个进程,进程所指包括 ...

  10. 安装nodejs搭建ghost个人博客

    记录一下今天在linux下折腾nodejs的过程,相互学习: (不知道为什么用源代码安装,调用npm的时候老是会出现找不到npmlog的 错误,后来换用下了个二进制 来搞,假设那个牛牛知道为什么.希望 ...