为ASP.NET MVC创建一个基于Mini容器的ControllerFactory

背景

     随着Asp.net mvc的越来越流行,关于和Mvc整合的DI容器也非常的多,而Mini容器一致没有把整合的方案发布出来,以至于不时的收到有些网友询问这些事,于是便有了该文。[源代码从这里下载,Mini容器官方地址]

解决方案

      创建自定义工厂          

   public class NLiteControllerFactory : DefaultControllerFactory
{
private IServiceLocator ServiceLocator;
public NLiteControllerFactory(IServiceLocator serviceLocator)
{
this.ServiceLocator = serviceLocator;
}

protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
{
return (IController)ServiceLocator.Get(controllerType);
}
}

Demo 例子

     为了演示效果效果, 用Artech兄的为ASP.NET MVC创建一个基于Unity的ControllerFactory这篇博客的例子了. 要创建一个维护联系人的应用,我们通过具有如下定义的Contact类型表示联系人,而IContactRepository接口定义了一个从存储中获取所有联系人的GetAllContacts方法,DefaultContactRepository是对IContactRepository接口的实现

    public class Contact
{
public string Name { get; set; }
public string Gender { get; set; }
public string Address { get; set; }
}

[Contract]
public interface IContactRepository
{
IEnumerable<Contact> GetAllContacts();
}

public class DefaultContactRepository : IContactRepository
{
public IEnumerable<Contact> GetAllContacts()
{
yield return new Contact
{
Name = "Zhang San",
Gender = "Male",
Address = "#328, XingHu Street, Su Zhou, Jiang Su Province, PRC."
};

yield return new Contact
{
Name = "Li Si",
Gender = "Female",
Address = "#328, Jin Ji Hu Road, Su Zhou, Jiang Su Province, PRC."
};
}
}

 
     我们在Web应用的主页显示联系人列表,为此我创建了如下一个HomeController。在这里我们演示的是构造器注入,所以我们通过构造函数指定的IContactRepository对象来初始化Repository属性。在Action方法Index中调用IContactRepository的GetAllContacts方法为对应的View指定Model。  
 
    public class HomeController : Controller
{
public IContactRepository Repository { get; private set; }
public HomeController(IContactRepository repository)
{
this.Repository = repository;
}
public ActionResult Index()
{
return View(this.Repository.GetAllContacts());
}

}

   在Global 文件中注册Mvc 的自定义控制器工厂
    public class MvcApplication : System.Web.HttpApplication
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
}

public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("favicon.ico");
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);

}

protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();

RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);

//创建Mini容器
NLiteEnvironment.Refresh();

//设置组件的生命周期缺省是临时的
LifestyleType.Default = LifestyleFlags.Transient;

//注册联系人仓储组件
ServiceRegistry.Register<DefaultContactRepository>();

//设置自定义控制器工厂
ControllerBuilder.Current.SetControllerFactory(new NLiteControllerFactory(ServiceLocator.Current));
}
    Index.cshtml代码如下所示,这是一个Model类型为IEnumerable<Contact>的View,它将所有的联系人信息列出来。 
 @model IEnumerable< NLite.Mvc.Models.Contact>
@{
ViewBag.Title = "Index";
}

<h2>Contact List</h2>

<div>
<ul>
@foreach (var contact in this.Model)
{
<li>
<h3>@contact.Name</h3>
<p>Gender: @contact.Gender</p>
<p>Address: @contact.Address</p>
<hr />
</li>
}
</ul>
</div>
  运行浏览器显示效果

posted @ 2011-12-19 12:13  风云  阅读(1765)  评论(9编辑  收藏  举报