Unity 在MVC上的应用(上:思路整理)
2011-05-15 11:01 bugfly 阅读(3456) 评论(7) 编辑 收藏 举报前言
卧病数月,颓废的日子。以前向往的未来一一被真几个月的辛酸打碎了,但未来依然要吃饭,所以打算写一个简短MVC系列来回顾IOC的应用,过中将会有实际开发中解决常见问题的方法。
注意:本系列每一篇文章和上一篇并无必然的承接关系,但所应用到的技术点是有先后顺序的,你将会从文章的应用上发现。
系列目录
Unity 在MVC上的应用(扩展篇:JQuery AJAX)
Unity 在MVC上的应用(扩展篇:事务控制-前篇ActionFilter)
Unity 在MVC上的应用(扩展篇:事务控制-后篇Unit Of Work)
Unity 在MVC上的应用(扩展篇:日志管理NLog)
正题
在上篇,我会通过一个简单的MVC例子来做一个DEMO,而并没有使用Unity,目的在于告诉对IOC应用场合不清晰的朋友面对什么情况使用IOC。各个这个例子很简单 (*^__^*) 嘻嘻……
本次教程使用的是MVC开发框架,结合Repository模式来展开。上篇暂时没有使用到Unity。
一如既往,先看看DEMO的物理结构图。
那些文件我就不一一叙述了,也不难理解。
先看看大致的运行流程。
Step 1
登录账号是HuntSoul 密码是123456 (*^__^*) 嘻嘻……
Step 2
这里登录成功的画面。我们点开“任务列表” Check Check今日有什么任务 ~(X X)~
Step 3
返回一下 XD,点开“打开仓库”!看看我们仓库的武器 XD
Step 4
好了,大致的流程就是这个摸样,正如我所说很简单~下面我们来看看这些简单而丑陋的代码 XD。
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace UnityAndMVC2_Demo2.Models
{
public class Entity
{
public int ID { get; set; }
}
}
Entity类作用在于标示对象。
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace UnityAndMVC2_Demo2.Models
{
public class Account:Entity
{
public string AccountID { get; set; }
public string AccountPwd { get; set; }
public string LickName{get;set;}
public string Age { get; set; }
public string Email { get; set; }
public string Cellphone { get; set; }
public List<Task> Tasks { get; set; }
public List<StoreHouse> Stores { get; set; }
}
}
这个是我们的 账号模型,和传统的游戏账号相比,当然这个简单很多,不过基于教程,我们无需太过复杂,恰到理解就可以了,以上英文我想你们都不用我一一解释其属性了吧?XD 要提一提的是,本教程没有使用到数据库,所以对于DB First的程序员,可能比较难理解,不过这个刚好是给你们一个新的视野去尝试面向对象(OO),这种方式貌似就是业界所说的Code First吧?或者我所理解的Model First~XD. 还是要解释一下关键的地方。 Account类有两个聚合列表对象Task(任务)和StoreHouse(仓库),是一对多关系。这里的仓库有点纠结,写教程的时候一时想歪了,明白我说的朋友就凑合看吧,哈哈。墨迹了这么多,下面的Model代码就不一一解释了。
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace UnityAndMVC2_Demo2.Models
{
public class Task : Entity
{
public string TaskName { get; set; }
public string TaskContent { get; set; }
public string TaskStatus { get; set; }
public Account Account { get; set; }
}
}
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace UnityAndMVC2_Demo2.Models
{
public class StoreHouse : Entity
{
public string GoodsName { get;set;}
public int GoodsNum{get;set;}
public float GoodsKg { get; set; }
public Account Account { get; set; }
}
}
好了,刚才说到我没使用数据库,那图片上的数据如何解释?恩,聪明的你已经想到了,那个DBContext是一个数据生成类,说白了就是一个假的数据库,为了测试,这个必需的,大家无需太过在意我的方式,你喜欢的可以随意模拟一个DB,用NBuilder也可以~不一一解释用法。来看看DBContext
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace UnityAndMVC2_Demo2.Models
{
public class DBContext
{
public List<Account> Accounts { get; set; }
public DBContext()
{
Accounts = new List<Account>();
Account n_account = new Account()
{
ID = 1,
AccountID = "HuntSoul",
AccountPwd = "123456",
LickName = "桀骜的灵魂",
Age = "44",
Cellphone = "139XXXXXXXXX",
Email = "31580941X@qq.com",
Tasks = new List<Task>() {
new Task(){
ID=1,
TaskName="Unity And MVC practice Demo2",
TaskContent="...",
TaskStatus="已完成"
}
,
new Task(){
ID=2,
TaskName="每日打酱油",
TaskContent="...",
TaskStatus="未完成"
}
},
Stores = new List<StoreHouse>()
{
new StoreHouse(){
ID=1,
GoodsName="希利欧之魂",
GoodsNum=10,
GoodsKg=80
},
new StoreHouse(){
ID=2,
GoodsName="海格力斯之袭",
GoodsNum=30,
GoodsKg=150
},
new StoreHouse(){
ID=3,
GoodsName="克罗莉斯之吻",
GoodsNum=25,
GoodsKg=132
},
}
};
Accounts.Add(n_account);
}
}
}
此时此刻,我们应该看看Controller类了。打开HomeController
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using UnityAndMVC2_Demo2.Models;
namespace UnityAndMVC2_Demo2.Controllers
{
[HandleError]
public class HomeController : Controller
{
public AccountRepository _AccountRepository = new AccountRepository();
public TaskRepository _TaskRepository = new TaskRepository();
public StoreHouseRepository _StoreHouseRepository = new StoreHouseRepository();
[HttpGet]
public ActionResult Login()
{
return View();
}
[HttpPost]
public ActionResult Login(FormCollection Model)
{
Account n_account=new Account();
UpdateModel(n_account);
var n_dbUser=_AccountRepository.find(n_account.AccountID, n_account.AccountPwd);
if (n_dbUser != null)
{
HttpContext.Session["User"] = n_account.AccountID;
return View("Index", n_dbUser);
}
return View();
}
public ActionResult Index()
{
return View();
}
public ActionResult TaskDetails()
{
List<Task> n_taskList = this._TaskRepository.find(HttpContext.Session["User"].ToString());
return View(n_taskList);
}
public ActionResult StoreHouseDetails()
{
List<StoreHouse> n_storeHouseList = this._StoreHouseRepository.find(HttpContext.Session["User"].ToString());
return View(n_storeHouseList);
}
}
}
不算复杂,就几个ACTION.对应的就是登录画面和菜单管理画面的操作。不墨迹意思了。
如代码上可以看到,有三个Repository实体类。见以下代码。
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace UnityAndMVC2_Demo2.Models
{
public class AccountRepository
{
public DBContext _Context=new DBContext();
public Account find(int ID)
{
var n_result = from a in _Context.Accounts
select a;
return n_result.ToList().FirstOrDefault();
}
public Account find(string AccountID,string AccountPwd) {
var n_result = from a in _Context.Accounts
where a.AccountID.Equals(AccountID)&&a.AccountPwd.Equals(AccountPwd)
select a;
return n_result.ToList().FirstOrDefault();
}
}
}
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace UnityAndMVC2_Demo2.Models
{
public class TaskRepository
{
public DBContext _Context = new DBContext();
public List<Task> find(string AccountID)
{
var n_result = from a in _Context.Accounts
where a.AccountID.Equals(AccountID)
select a;
return n_result.FirstOrDefault().Tasks;
}
}
}
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace UnityAndMVC2_Demo2.Models
{
public class StoreHouseRepository
{
public DBContext _Context = new DBContext();
public List<StoreHouse> find(string AccountID)
{
var n_result = from a in _Context.Accounts
where a.AccountID.Equals(AccountID)
select a;
return n_result.FirstOrDefault().Stores;
}
}
}
这三个Repository实体,内容都是那么相似。。聪明的你一定在笑哥,为什么不重构一下,对对对,那个什么泛型Repository,不用急,在最后一篇将会重构Repository的。这里暂不列出内容,,,因为中篇还没写,(*^__^*) 嘻嘻……
我们再看看我们的HomeController代码,你会发现,有不少直接new的对象,就是那三个Repository啦,全篇重点就是这里,直接new的结果是,过分耦合,repository的生命周期完全和Controller绑定了,结果就是,有一天要重构这几个Repository实体的方法,你修改的就不是单单那几个要重构的Repository了,而是每个引用到他们的地方,可能你还觉得问题不明显,这样吧,如果有1000个Repository实体,有100个Controller引用它们,重构它们原本find的行为,改为Lookout()行为。。这个悲剧能看到了吧?所以呢,我们不能直接就new它们到其他类里面,要降低耦合程度,为未来的维护做好准备,什么方法可以解开耦合呢?可以告诉你的很多,不过,我觉得最好的方式就是使用IOC容器,通过容器去关系注入关系,恩~完了,下篇我们将会引入Unity来解开这段耦合关系。很久没用过了。给点时间我,(*^__^*) 嘻嘻……
最后附上本篇的DEMO代码
作者:桀骜的灵魂
出处:http://www.cnblogs.com/HuntSoul/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。