html5中文学习网

您的位置: 首页 > 网络编程 > ASP.NET » 正文

ASP.NET MVC中使用Unity Ioc Container_.NET教程_编程技术

[ ] 已经帮助:人解决问题

  在MVC中,控制器依赖于模型对数据进行处理,也可以说执行业务逻辑。我们可以使用依赖注入(DI)在控制层分离模型层,这边要用到Repository模式,在领域驱动设计(DDD)中,Repository翻译为仓储,顾名思义,就是储存东西的仓库,可以理解为一种用来封装存储,读取和查找行为的机制,它模拟了一个对象集合。使用依赖注入(DI)就是对Repository进行管理,用于解决它与控制器之间耦合度问题,下面我们一步一步做一个简单示例。DfZHTML5中文学习网 - HTML5先行者学习网

安装Unity

  首先我们需要新建一个UnityMVCDemo项目ASP.NET MVC4.0),选择工具-库程序包管理器-程序包管理控制台,输入“Install-Package Unity.Mvc4”命令,VS2010可能需要先安装NuGet。DfZHTML5中文学习网 - HTML5先行者学习网

DfZHTML5中文学习网 - HTML5先行者学习网

  或者通过工具-库程序包管理器-管理解决方案的 NuGet 程序包,通过联机搜索“Unity.Mvc4”进行安装。DfZHTML5中文学习网 - HTML5先行者学习网

DfZHTML5中文学习网 - HTML5先行者学习网

  在安装过程中可能会遇到下面这样错误:DfZHTML5中文学习网 - HTML5先行者学习网

DfZHTML5中文学习网 - HTML5先行者学习网

  根据异常信息,可以肯定是项目的.net framework版本无法安装Unity,这种安装VS会自动搜索Unity最新版本,但是最新版本往往有. net framework版本要求,不知道有没有指定Unity版本安装,可以看到我们安装的是Unity3.0版本,修改一下项目. net framework的版本为4.5,重新安装就可以了。DfZHTML5中文学习网 - HTML5先行者学习网

  安装Unity成功后,我们发现项目中多了“Microsoft.Practices.Unity”和“Microsoft.Practices.Unity.Configuration”两个引用,还有一个Bootstrapper类文件,Bootstrapper翻译为引导程序,也就是Ioc容器。DfZHTML5中文学习网 - HTML5先行者学习网

public static class Bootstrapper
    {
        public static IUnityContainer Initialise()
        {
            var container = BuildUnityContainer();

            DependencyResolver.SetResolver(new UnityDependencyResolver(container));

            return container;
        }

        private static IUnityContainer BuildUnityContainer()
        {
            var container = new UnityContainer();

            // register all your components with the container here
            // it is NOT necessary to register your controllers

            // e.g. container.RegisterType<ITestService, TestService>();   
            RegisterTypes(container);

            return container;
        }

        public static void RegisterTypes(IUnityContainer container)
        {

        }
    }

添加服务层

  首先我们添加一个Article实体类:DfZHTML5中文学习网 - HTML5先行者学习网

/// <summary>
    /// Article实体类
    /// </summary>
    public class Article
    {
        public int Id { get; set; }
        public string Title { get; set; }
        public string Author { get; set; }
        public string Content { get; set; }
        public DateTime CreateTime { get; set; }
    }

 一般Repository都有一些相似的操作,比如增删改查,我们可以把它抽象为IArticleRepository接口,这样控制器依赖于抽象接口,而不依赖于具体实现Repository类,符合依赖倒置原则,我们才可以使用Unity进行依赖注入。DfZHTML5中文学习网 - HTML5先行者学习网

/// <summary>
    /// IArticleRepository接口
    /// </summary>
    public interface IArticleRepository
    {
        IEnumerable<Article> GetAll();
        Article Get(int id);
        Article Add(Article item);
        bool Update(Article item);
        bool Delete(int id);
    }

  创建ArticleRepository,依赖于IArticleRepository接口,实现基本操作。DfZHTML5中文学习网 - HTML5先行者学习网

public class ArticleRepository : IArticleRepository
    {
        private List<Article> Articles = new List<Article>();

        public ArticleRepository()
        {
            //添加演示数据
            Add(new Article { Id = 1, Title = "UnityMVCDemo1", Content = "UnityMVCDemo", Author = "xishuai", CreateTime = DateTime.Now });
            Add(new Article { Id = 2, Title = "UnityMVCDemo2", Content = "UnityMVCDemo", Author = "xishuai", CreateTime = DateTime.Now });
            Add(new Article { Id = 3, Title = "UnityMVCDemo2", Content = "UnityMVCDemo", Author = "xishuai", CreateTime = DateTime.Now });
        }
        /// <summary>
        /// 获取全部文章
        /// </summary>
        /// <returns></returns>
        public IEnumerable GetAll()
        {
            return Articles;
        }
        /// <summary>
        /// 通过ID获取文章
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public Article Get(int id)
        {
            return Articles.Find(p => p.Id == id);
        }
        /// <summary>
        /// 添加文章
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        public Article Add(Article item)
        {
            if (item == null)
            {
                throw new ArgumentNullException("item");
            }
            Articles.Add(item);
            return item;
        }
        /// <summary>
        /// 更新文章
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        public bool Update(Article item)
        {
            if (item == null)
            {
                throw new ArgumentNullException("item");
            }

            int index = Articles.FindIndex(p => p.Id == item.Id);
            if (index == -1)
            {
                return false;
            }
            Articles.RemoveAt(index);
            Articles.Add(item);
            return true;
        }
        /// <summary>
        /// 删除文章
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public bool Delete(int id)
        {
            Articles.RemoveAll(p => p.Id == id);
            return true;
        }
    }

IArticleRepository类型映射

  上面工作做好后,我们需要在Bootstrapper中的BuildUnityContainer方法添加此类型映射。DfZHTML5中文学习网 - HTML5先行者学习网

private static IUnityContainer BuildUnityContainer()        {            var container = new UnityContainer();            // register all your components with the container here            // it is NOT necessary to register your controllers            container.RegisterType<IArticleRepository, ArticleRepository>();            // e.g. container.RegisterType<ITestService, TestService>();                RegisterTypes(container);            return container;        }

 我们还可以在配置文件中添加类型映射,UnityContainer根据配置信息,自动注册相关类型,这样我们就只要改配置文件了,当然推荐是这种方法,配置文件:DfZHTML5中文学习网 - HTML5先行者学习网

<configSections>
    <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,
             Microsoft.Practices.Unity.Configuration" />
  </configSections>
  <unity>
    <containers>
      <container name="defaultContainer">
        <register type="UnityMVCDemo.Models.IArticleRepository, UnityMVCDemo" mapTo="UnityMVCDemo.Models.ArticleRepository, UnityMVCDemo"/>
      </container>
    </containers>
  </unity>

 注意configSections节点要放在configuration节点下的第一个节点,关于Unity的配置文件配置参照http://www.cnblogs.com/xishuai/p/3670292.html,加载配置文件代码:DfZHTML5中文学习网 - HTML5先行者学习网

1     UnityConfigurationSection configuration = (UnityConfigurationSection)ConfigurationManager.GetSection(UnityConfigurationSection.SectionName); 2     configuration.Configure(container, "defaultContainer");

  上面这段代码替换掉上面使用的RegisterType方法。DfZHTML5中文学习网 - HTML5先行者学习网

服务注入到控制器

  在ArticleController中我们使用是构造器注入方式,当然还有属性注入和方法注入,可以看到ArticleController依赖于抽象IArticleRepository接口,而并不是依赖于ArticleRepository具体实现类。DfZHTML5中文学习网 - HTML5先行者学习网

public class ArticleController : Controller
    {
        readonly IArticleRepository repository;
        //构造器注入
        public ArticleController(IArticleRepository repository)
        {
            this.repository = repository;
        }

        public ActionResult Index()
        {
            var data = repository.GetAll();
            return View(data);
        }
    }

Global.asax初始化

  做完上面的工作后,我们需要在Global.asax中的Application_Start方法添加依赖注入初始化。DfZHTML5中文学习网 - HTML5先行者学习网

// Note: For instructions on enabling IIS6 or IIS7 classic mode, 
    // visit 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);

            Bootstrapper.Initialise();
        }
    }

示例代码下载:http://pan.baidu.com/s/1qWoCy9eDfZHTML5中文学习网 - HTML5先行者学习网

DfZHTML5中文学习网 - HTML5先行者学习网
DfZHTML5中文学习网 - HTML5先行者学习网
(责任编辑:)
推荐书籍
推荐资讯
关于HTML5先行者 - 联系我们 - 广告服务 - 友情链接 - 网站地图 - 版权声明 - 人才招聘 - 帮助