ASP.NET MVC中使用Unity Ioc Container

來源:互聯網
上載者:User

  在MVC中,控制器依賴於模型對資料進行處理,也可以說執行商務邏輯。我們可以使用依賴注入(DI)在控制層分離模型層,這邊要用到Repository模式,在領域驅動設計(DDD)中,Repository翻譯為倉儲,顧名思義,就是儲存東西的倉庫,可以理解為一種用來封裝儲存,讀取和尋找行為的機制,它類比了一個對象集合。使用依賴注入(DI)就是對Repository進行管理,用於解決它與控制器之間耦合度問題,下面我們一步一步做一個簡單樣本。

安裝Unity

  首先我們需要建立一個UnityMVCDemo項目(ASP.NET MVC4.0),選擇工具-庫封裝管理員-程式包管理主控台,輸入“Install-Package Unity.Mvc4”命令,VS2010可能需要先安裝NuGet。

  或者通過工具-庫封裝管理員-管理解決方案的 NuGet 程式包,通過聯機搜尋“Unity.Mvc4”進行安裝。

  在安裝過程中可能會遇到下面這樣錯誤:

  根據異常資訊,可以肯定是項目的.net framework版本無法安裝Unity,這種安裝VS會自動搜尋Unity最新版本,但是最新版本往往有. net framework版本要求,不知道有沒有指定Unity版本安裝,可以看到我們安裝的是Unity3.0版本,修改一下項目. net framework的版本為4.5,重新安裝就可以了。

  安裝Unity成功後,我們發現項目中多了“Microsoft.Practices.Unity”和“Microsoft.Practices.Unity.Configuration”兩個引用,還有一個Bootstrapper類檔案,Bootstrapper翻譯為引導程式,也就是Ioc容器。

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實體類:

/// <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進行依賴注入。

/// <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介面,實現基本操作。

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方法添加此類型映射。

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根據配置資訊,自動註冊相互關聯類型,這樣我們就只要改設定檔了,當然推薦是這種方法,設定檔:

<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,載入設定檔代碼:

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

  上面這段代碼替換掉上面使用的RegisterType方法。

服務注入到控制器

  在ArticleController中我們使用是構造器注入方式,當然還有屬性注入和方法注入,可以看到ArticleController依賴於抽象IArticleRepository介面,而並不是依賴於ArticleRepository具體實作類別。

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方法添加依賴注入初始化。

// 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/1qWoCy9e。



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.