Pro Aspnet MVC 4读书笔记(2) - The MVC Pattern
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的更多相关文章
- 【Tools】Pro Git 一二章读书笔记
记得知乎以前有个问题说:如果用一天的时间学习一门技能,选什么好?里面有个说学会Git是个很不错选择,今天就抽时间感受下Git的魅力吧. Pro Git (Scott Chacon) 读书笔记: ...
- [Git00] Pro Git 一二章读书笔记
记得知乎以前有个问题说:如果用一天的时间学习一门技能,选什么好?里面有个说学会Git是个很不错选择,今天就抽时间感受下Git的魅力吧. Pro Git (Scott Chacon) 读书笔记: ...
- Pro Aspnet MVC 4读书笔记(1) - Your First MVC Application
Listing 2-1. The default contents of the HomeController class using System; using System.Collections ...
- Pro Aspnet MVC 4读书笔记(4) - Working with Razor
Listing 5-1. Creating a Simple Domain Model Class using System; using System.Collections.Generic; us ...
- Pro Aspnet MVC 4读书笔记(3) - Essential Language Features
Listing 4-1. The Initial Content of the Home Controller using System; using System.Collections.Gener ...
- 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 ...
- 《Pro Android Graphics》读书笔记之第四节
Android Procedural Animation: : XML, Concepts and Optimization Procedural Animation Concepts: Tweens ...
- 《Pro Android Graphics》读书笔记之第三节
Android Frame Animation: XML, Concepts and Optimization Frame Animation Concepts: Cels, Framerate, a ...
- 《Pro Android Graphics》读书笔记之第六节
Android UI Layouts: Graphics Design Using the ViewGroup Class Android ViewGroup Superclass: A Founda ...
随机推荐
- singleton pattern
1 normal mode class Singleton { private Singleton(){}; Singleton singleton; static Singleton getInst ...
- [视频解说]0基础课程-运营商-Java它J2se
本节解说 运营商应用 Java 算被分成: 算术运算符 颂值运营商 逻辑运算符 位运算符 元运算符 这里录制了 视频解说这几大类运算符,并有练习题提供大家 面试题: 1. 最有效率的方式算出2乘以8等 ...
- effective c++ 条款9 do not call virtual function in constructor or deconstructor
在构造函数中不要调用virtual函数,调用了也不会有预期的效果. 举个例子 class Transaction { public: Transaction() { log(); } ; } clas ...
- effective c++ prefer const,enum, inline to #defines
学习心得 对于纯常量,最好以const对象或者enums替换#define #define FIRST 3 //not good enum { first=1, second=2 } ; int nu ...
- poj 3375 Network Connection
今天在叉姐的群里找点题目做,这题目还是很好的:提意思如下 [有M个可以提供计算机网络的端口和N台计算机(计算机数量少于端口数),每个端口和计算机有一个坐标(一维的)!其中端口与计算机链接的距离 |x ...
- Android Stuido怎样查看快捷键冲突?
看了这篇文章Android Studio怎样查看资源或者函数在哪些类中被引用.知道了快捷键失效的原因,当中有一个原因就是快捷键冲突.那怎样查看快捷键哪些项冲突了呢? Android Studio要查看 ...
- Windows8.1和Ubuntu14.04双系统卸载Ubuntu參考教程[图]
我之前编写并公布了<Windows8.1安装Ubuntu14.04双系统參考教程及双硬盘注意事项>这篇教程,而本文提供的卸载Ubuntu方法适用于这篇教程,其它方法安装的Ubuntu可适当 ...
- 【Android】android图片轮播
第一步,先写一个布局文件 <com.main.util.SlideShowView android:id="@+id/slideshowView" android:layou ...
- 最简单的视音频播放演示样例8:DirectSound播放PCM
===================================================== 最简单的视音频播放演示样例系列文章列表: 最简单的视音频播放演示样例1:总述 最简单的视音频 ...
- 1!到n!的和
Time Limit: 1 Sec Memory Limit: 64 MB Submit: 23 Solved: 14 [Submit][Status][Web Board] Descriptio ...