本文是继 ASP.NET MVC 系列之 (依赖注入(DI)和Ninject) 文章所做的一个示例,用来更好的理解Ninject在MVC项目中的实际应用过程。 建议大家为了更好的学习本节,请先对ASP.NET MVC 系列之 (依赖注入(DI)和Ninject)进行阅读了解。
一、环境搭建
首先创建一个空的解决方案,在解决方案下创建一个MVC空应用程序以及一个类库程序。结构如下
并在两个应用程序中引用Ninject程序集,且在MVC应用程序中添加对Domian程序的引用。
二、准备实体
/// <summary>
/// “专辑” 实体
/// </summary>
public class Album
{
public int AlbumId { get; set; }
public string Title { get; set; }
public decimal Price { get; set; }
public string AlbumArtUrl { get; set; }
}
在后面我们肯定要提供一种访问数据库的方法,在此之前我们为数据使用者提供一个IAlbumRepository接口,里面存在一个Albums属性,代表专辑的数据集合。现在我们添加一个Abstract文件夹保存这些接口。 接口代码如下:
public interface IAlbumRepository
{
List<Album> Albums { get; }
}
然后添加一个AlbumRepository类,继承自IAlbumRepository、添加到Specific文件夹下。为了更加简洁明了,在此类中我们没有进行数据库的访问而是直接初始化数据了。 AlbumRepository类代码如下:
public class AlbumRepository : IAlbumRepository
{
public List<Entitys.Album> Albums
{
get { return GetAlbums(); }
}
private static List<Album> GetAlbums()
{
return new List<Album>()
{
new Album(){ AlbumId=1,Title="Logn Fo",Price=25.5m},
new Album(){ AlbumId=2,Title="First IF",Price=35.5m},
new Album(){ AlbumId=3,Title="LineSm",Price=45.5m},
new Album(){ AlbumId=4,Title="ComNur",Price=55.5m},
};
}
}
现在类库工程中基本上已经完成,下面我们将视线转换到MVC 应用程序中。
四、添加Controller Factory
有两种方式可以进行,下面我们一一讲述两种方式
1、首先通过继承内置的Controller工厂类DefaultControllerFactory, 通过下面的AddBindings中的代码,ninjectIkernel将IAlbumRepository绑定到AlbumRepository,在访问IAlbumRepository的同时,自动创建AlbumRepository的实例。
public class NinjectControllerFactory : DefaultControllerFactory
{
private IKernel ninjectIkernel;
public NinjectControllerFactory()
{
ninjectIkernel = new StandardKernel();
AddBindings();
}
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
return controllerType == null ? null : (IController)ninjectIkernel.Get(controllerType);
}
private void AddBindings()
{
//添加依赖绑定
ninjectIkernel.Bind<IAlbumRepository>().To<AlbumRepository>();
}
}
并在Global.asax文件中注册
//注册
ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory());
2、通过Ioc反转器进行注册,实现过程类似。
public class NinjectDependencyResolver : IDependencyResolver
{
private IKernel ninjectIkernel;
public NinjectDependencyResolver()
{
ninjectIkernel = new StandardKernel();
AddBindings();
}
public void AddBindings()
{
//添加依赖绑定
ninjectIkernel.Bind<IAlbumRepository>().To<AlbumRepository>();
}
public object GetService(Type serviceType)
{
return ninjectIkernel.Get(serviceType);
}
public IEnumerable<object> GetServices(Type serviceType)
{
return ninjectIkernel.GetAll(serviceType);
}
}
在Global.asax文件中注册
DependencyResolver.SetResolver(new NinjectDependencyResolver());
四、界面展示
添加一个空控制器,在里面添加一个展示的方法
public class StoreManagerController : Controller
{
private IAlbumRepository repository;
public StoreManagerController(IAlbumRepository albumRepository)
{
repository = albumRepository;
}
//
// GET: /StoreManager/
public ActionResult Index()
{
return View(repository.Albums);
}
}
添加视图 视图代码:
@model IEnumerable<MusicStore.Domain.Entitys.Album>
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
@foreach (var item in Model)
{
<div class="item" style="border-bottom:1px dashed silver;">
<h3>@item.Title</h3>
<p>价格:@item.Price.ToString("c") </p>
</div>
}
在显示之前将默认控制器路径改变
最终结果: