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 ...
随机推荐
- listary文件查找程序下载和使用
资源:PHP开发学习门户网站 地址:http://bbs.phpthinking.com/forum.php?mod=viewthread&tid=173 Listary 是一款有用的国产Wi ...
- 这么多的技术,作为一个freshman,什么研究?
科学技术,从哪里学习? 杨问了我几个最近:"如何学习技术?".说实话,其实,我自己只是一个资深兄弟.对于这个答案.这是更难以在本身回答. 可是.既然比师弟们多吃了几年 ...
- UseCase事件描述叙事流规范
文化/fasiondog 整理的用例需求编写规范.分享部分UseCase事件描述叙事流规范.其中.标准5~10.12来自哪里<编写有效用例>([美国] Alistair Cockburn ...
- php:修改NetBeans默认字体
在Netbeans中由于使用了Swing进行开发,所以其中界面的字体也是由Java虚拟机进行配置而不是随操作系统的.在安装完Netbeans后默认的字体大小是11px.而在Windows下的宋体最小支 ...
- bin home
bin=$(cd `dirname $0`;pwd)home=$(dirname $bin)
- 在深入分析:Android在app之间的相互作用(一个,使用Action)
我们开发Android App时间应用,有些需求,我们需要启动另一App为了应对一些逻辑.例如,我们需要映射基于地址调用系统或相关Map App,所以,我们不自己有App在相应的功能的制备.而是通过I ...
- Dictionary带来的一种隐式内存泄漏
当心Dictionary带来的一种隐式内存泄漏 最近在看Dictionary的源代码的时候, 突然想到Dictionary的不当使用中有一种隐含内存泄漏的可能. 简化使用场景 小A正在写一个简单的图书 ...
- C++输入输出进制、数据宽度与对齐、精度、取整
cout<<setw(4)<<setfill('0')<<a<<endl; ////样例输出 a=41输出 0041 1.数的进制 [转载]未完的c++ ...
- myeclipse如何恢复已删除的文件和代码
这是一篇文章分享秘诀:myeclipse恢复意外删除的文件和代码 [ 恢复误删文件 ] 今天在写代码的时候,不小心把一个包给删除了,然后这个包下全部的文件都没了,相信非常多人都有类似的经历. 幸好my ...
- C标签之forEach
<c:forEach>标签用于通用数据循环,它有下面属性 属 性 描 述 是否必须 缺省值 items 进行循环的项目 否 无 begin 開始条件 否 0 end 结束条件 否 集合中的 ...