前言
为了符合后面更新后的重构系统,文章于2016-11-1日重写
本节重构一下代码,采用IOC控制反转,也就是依赖注入
您可以访问http://unity.codeplex.com/releases得到最新版本的Unity现在。
这里http://unity.codeplex.com/documentation我们找到了帮助文档大家可以下载下来看看
当然,如果您在您的visual studio 中安装了Nuget 包管理器,你可以直接在Nuget中获取到最新版本的Unity。
我们采用的是构造函数注入,运行时注入。
【ASP.Net MVC3 】使用Unity 实现依赖注入 这是园内大虾写得这块知识点,大家进去看看
为什么要使用注入
我们反转了对依赖的控制。不是使用new关键字创建一个实例,而是将这种行为委托给了第三方实现(容器)
安装Nuget Unity包
分别按照在Apps.Web,Apps.BLL,Apps.Core中
在Apps.Core中添加以下2个类:主要是注入配置使用
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Apps.BLL;
using Apps.DAL;
using Apps.IBLL;
using Apps.IDAL;
using Microsoft.Practices.Unity; namespace Apps.Core
{
public class DependencyRegisterType
{
//系统注入
public static void Container_Sys(ref UnityContainer container)
{
container.RegisterType<ISysSampleBLL, SysSampleBLL>();//样例
container.RegisterType<ISysSampleRepository, SysSampleRepository>();
}
}
}
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.Mvc;
using Microsoft.Practices.Unity; namespace Apps.Core
{
public class UnityDependencyResolver : IDependencyResolver
{
private const string HttpContextKey = "perRequestContainer"; private readonly IUnityContainer _container; public UnityDependencyResolver(IUnityContainer container)
{
_container = container;
} public object GetService(Type serviceType)
{
if (typeof(IController).IsAssignableFrom(serviceType))
{
return ChildContainer.Resolve(serviceType);
} return IsRegistered(serviceType) ? ChildContainer.Resolve(serviceType) : null;
} public IEnumerable<object> GetServices(Type serviceType)
{
if (IsRegistered(serviceType))
{
yield return ChildContainer.Resolve(serviceType);
} foreach (var service in ChildContainer.ResolveAll(serviceType))
{
yield return service;
}
} protected IUnityContainer ChildContainer
{
get
{
var childContainer = HttpContext.Current.Items[HttpContextKey] as IUnityContainer; if (childContainer == null)
{
HttpContext.Current.Items[HttpContextKey] = childContainer = _container.CreateChildContainer();
} return childContainer;
}
} public static void DisposeOfChildContainer()
{
var childContainer = HttpContext.Current.Items[HttpContextKey] as IUnityContainer; if (childContainer != null)
{
childContainer.Dispose();
}
} private bool IsRegistered(Type typeToCheck)
{
var isRegistered = true; if (typeToCheck.IsInterface || typeToCheck.IsAbstract)
{
isRegistered = ChildContainer.IsRegistered(typeToCheck); if (!isRegistered && typeToCheck.IsGenericType)
{
var openGenericType = typeToCheck.GetGenericTypeDefinition(); isRegistered = ChildContainer.IsRegistered(openGenericType);
}
} return isRegistered;
}
}
}
UnityDependencyResolver.cs
在系统开始运行时候我们就把构造函数注入。所以我们要在Global文件写入代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using Apps.Core;
using Microsoft.Practices.Unity; namespace Apps.Web
{
// 注意: 有关启用 IIS6 或 IIS7 经典模式的说明,
// 请访问 http://go.microsoft.com/?LinkId=9394801 public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas(); WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
//启用压缩
BundleTable.EnableOptimizations = true;
BundleConfig.RegisterBundles(BundleTable.Bundles);
AuthConfig.RegisterAuth(); //注入 Ioc
var container = new UnityContainer();
DependencyRegisterType.Container_Sys(ref container);
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
}
}
}
Global.asax.cs
好了,我们已经把
ISysSampleBLL, SysSampleBLL
ISysSampleRepository, SysSampleRepository
关系注入到系统了
自定义模型
由于EF生成的实体模型是拥有事务状态的,我们需要为SysSample的类再次定义个模型,SysSampleModel,这个模型我们可以加属性,序列化、脱离事物
在Apps.Models新建文件夹Sys,如非特别说明,Sys代表系统,一个Areas区域对应一个文件,区域我们以后会用到
using System;
using System.ComponentModel.DataAnnotations;
using System.Runtime.Serialization;
namespace Apps.Models.Sys
{
public class SysSampleModel
{
[Display(Name = "ID")]
public string Id { get; set; } [Display(Name = "名称")]
public string Name { get; set; } [Display(Name = "年龄")]
[Range(,)]
public int? Age { get; set; } [Display(Name = "生日")]
public DateTime? Bir { get; set; } [Display(Name = "照片")]
public string Photo { get; set; } [Display(Name = "简介")]
public string Note { get; set; } [Display(Name = "创建时间")]
public DateTime? CreateTime { get; set; } }
}
接下来我们重新写过IBLL,BLL,controller代码,DAL,IDAL的代码是没问题的,很专注底层
BLL引用Microsoft.Practices.Unity类库
修改后的代码
using System.Collections.Generic;
using Apps.Models.Sys; namespace Apps.IBLL
{ public interface ISysSampleBLL
{
/// <summary>
/// 获取列表
/// </summary>
/// <param name="pager">JQgrid分页</param>
/// <param name="queryStr">搜索条件</param>
/// <returns>列表</returns>
List<SysSampleModel> GetList(string queryStr);
/// <summary>
/// 创建一个实体
/// </summary>
/// <param name="errors">持久的错误信息</param>
/// <param name="model">模型</param>
/// <returns>是否成功</returns>
bool Create(SysSampleModel model);
/// <summary>
/// 删除一个实体
/// </summary>
/// <param name="errors">持久的错误信息</param>
/// <param name="id">id</param>
/// <returns>是否成功</returns>
bool Delete(string id); /// <summary>
/// 修改一个实体
/// </summary>
/// <param name="errors">持久的错误信息</param>
/// <param name="model">模型</param>
/// <returns>是否成功</returns>
bool Edit(SysSampleModel model);
/// <summary>
/// 根据ID获得一个Model实体
/// </summary>
/// <param name="id">id</param>
/// <returns>Model实体</returns>
SysSampleModel GetById(string id);
/// <summary>
/// 判断是否存在实体
/// </summary>
/// <param name="id">主键ID</param>
/// <returns>是否存在</returns>
bool IsExist(string id);
}
}
ISysSampleBLL.cs
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Practices.Unity;
using Apps.Models;
using Apps.Common;
using Apps.Models.Sys;
using Apps.IBLL;
using Apps.IDAL; namespace Apps.BLL
{
public class SysSampleBLL : ISysSampleBLL
{
DBContainer db = new DBContainer();
[Dependency]
public ISysSampleRepository Rep { get; set; }
/// <summary>
/// 获取列表
/// </summary>
/// <param name="pager">JQgrid分页</param>
/// <param name="queryStr">搜索条件</param>
/// <returns>列表</returns>
public List<SysSampleModel> GetList(string queryStr)
{ IQueryable<SysSample> queryData = null;
queryData = Rep.GetList(db);
return CreateModelList(ref queryData);
}
private List<SysSampleModel> CreateModelList(ref IQueryable<SysSample> queryData)
{ List<SysSampleModel> modelList = (from r in queryData
select new SysSampleModel
{
Id = r.Id,
Name = r.Name,
Age = r.Age,
Bir = r.Bir,
Photo = r.Photo,
Note = r.Note,
CreateTime = r.CreateTime, }).ToList(); return modelList;
} /// <summary>
/// 创建一个实体
/// </summary>
/// <param name="errors">持久的错误信息</param>
/// <param name="model">模型</param>
/// <returns>是否成功</returns>
public bool Create( SysSampleModel model)
{
try
{
SysSample entity = Rep.GetById(model.Id);
if (entity != null)
{
return false;
}
entity = new SysSample();
entity.Id = model.Id;
entity.Name = model.Name;
entity.Age = model.Age;
entity.Bir = model.Bir;
entity.Photo = model.Photo;
entity.Note = model.Note;
entity.CreateTime = model.CreateTime; if (Rep.Create(entity) == )
{
return true;
}
else
{
return false;
}
}
catch (Exception ex)
{
//ExceptionHander.WriteException(ex);
return false;
}
}
/// <summary>
/// 删除一个实体
/// </summary>
/// <param name="errors">持久的错误信息</param>
/// <param name="id">id</param>
/// <returns>是否成功</returns>
public bool Delete(string id)
{
try
{
if (Rep.Delete(id) == )
{
return true;
}
else
{
return false;
}
}
catch (Exception ex)
{
return false;
}
} /// <summary>
/// 修改一个实体
/// </summary>
/// <param name="errors">持久的错误信息</param>
/// <param name="model">模型</param>
/// <returns>是否成功</returns>
public bool Edit(SysSampleModel model)
{
try
{
SysSample entity = Rep.GetById(model.Id);
if (entity == null)
{
return false;
}
entity.Name = model.Name;
entity.Age = model.Age;
entity.Bir = model.Bir;
entity.Photo = model.Photo;
entity.Note = model.Note; if (Rep.Edit(entity) == )
{
return true;
}
else
{ return false;
} }
catch (Exception ex)
{ //ExceptionHander.WriteException(ex);
return false;
}
}
/// <summary>
/// 判断是否存在实体
/// </summary>
/// <param name="id">主键ID</param>
/// <returns>是否存在</returns>
public bool IsExists(string id)
{
if (db.SysSample.SingleOrDefault(a => a.Id == id) != null)
{
return true;
}
return false;
}
/// <summary>
/// 根据ID获得一个实体
/// </summary>
/// <param name="id">id</param>
/// <returns>实体</returns>
public SysSampleModel GetById(string id)
{
if (IsExist(id))
{
SysSample entity = Rep.GetById(id);
SysSampleModel model = new SysSampleModel();
model.Id = entity.Id;
model.Name = entity.Name;
model.Age = entity.Age;
model.Bir = entity.Bir;
model.Photo = entity.Photo;
model.Note = entity.Note;
model.CreateTime = entity.CreateTime; return model;
}
else
{
return new SysSampleModel();
}
} /// <summary>
/// 判断一个实体是否存在
/// </summary>
/// <param name="id">id</param>
/// <returns>是否存在 true or false</returns>
public bool IsExist(string id)
{
return Rep.IsExist(id);
}
}
}
SysSampleBLL.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Apps.BLL;
using Apps.IBLL;
using Apps.Models;
using Apps.Models.Sys;
using Microsoft.Practices.Unity; namespace Apps.Web.Controllers
{
public class SysSampleController : Controller
{
//
// GET: /SysSample/
/// <summary>
/// 业务层注入
/// </summary>
[Dependency]
public ISysSampleBLL m_BLL { get; set; }
public ActionResult Index()
{
List<SysSampleModel> list = m_BLL.GetList("");
return View(list);
} }
}
SysSampleController.cs
@model List<App.Models.Sys.SysSampleModel> @{
Layout = null;
} <!DOCTYPE html> <html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
</head>
<body>
<p>
@Html.ActionLink("Create New", "Create")
</p>
<table>
<tr>
<th>
名称
</th>
<th>
年龄
</th>
<th>
生日
</th>
<th>
照片
</th>
<th>
备注
</th>
<th>
创建时间
</th>
<th></th>
</tr> @foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.Age)
</td>
<td>
@Html.DisplayFor(modelItem => item.Bir)
</td>
<td>
@Html.DisplayFor(modelItem => item.Photo)
</td>
<td>
@Html.DisplayFor(modelItem => item.Note)
</td>
<td>
@Html.DisplayFor(modelItem => item.CreateTime)
</td>
<td>
@Html.ActionLink("Edit", "Edit", new { id=item.Id }) |
@Html.ActionLink("Details", "Details", new { id=item.Id }) |
@Html.ActionLink("Delete", "Delete", new { id=item.Id })
</td>
</tr>
} </table>
</body>
</html>
View视图
因为SysSample在BLL层已经被释放掉了,大家要注意一下所以视图我们要改下
大家把代码下载下来,跟我们第5讲糟糕的代码对比一下。我们的代码优化了,清晰了,构造器能自动释放内存了,无需要实例化了。
当然预览的效果是一样的
下一讲,返回json格式与DataGrid结合,实现分页。