ASP.NET Web API實踐系列07,獲取數據, 使用Ninject實現依賴倒置,使用Knockout實現頁面元素和視圖模型的雙向綁定

本篇接着上一篇"ASP.NET Web API實踐系列06, 在ASP.NET MVC 4 基礎上增長使用ASP.NET WEB API",嘗試獲取數據。javascript

 

在Models文件夾下建立Comment類:css

 

namespace MvcApplication5.Models
{
    public class Comment
    {
        public int ID { get; set; }
        public string Author { get; set; }
        public string Text { get; set; }
        public string Email { get; set; }
    }
}

在Repository文件夾下建立ICommentRepository接口:html

 

using System.Collections.Generic;
using MvcApplication5.Models;
namespace MvcApplication5.Repository
{
    public interface ICommentRepository
    {
        IEnumerable<Comment> Get();
        bool TryGet(int id, out Comment comment);
        Comment Add(Comment comment);
        bool Delete(int id);
        bool Update(Comment comment);
    }
}    

 

在Repository文件夾下建立CommentRepository類,實現ICommentRepository接口:前端

 

using  System.Collections.Generic;
using System.Linq;
using MvcApplication5.Models;
namespace MvcApplication5.Repository
{
    public class CommentRepository : ICommentRepository
    {
        private int nextID = 0;
        Dictionary<int, Comment>  comments = new Dictionary<int, Comment>();
        public CommentRepository()
        {
            Add(new Comment
            {
                ID = 1,
                Text = @"I sat here trying really hard to think of something profound to write for my comment but was left with nothing interesting to say other than this droning on and on that I'm doing right now. But sometimes, droning on and on serves a purpose. For example, this comment appears more realistic without resorting to Lorem Ipsum.",
                Author = "Phil",
                Email = "haacked@gmail.com",
            });
            Add(new Comment
            {
                ID = 1,
                Text = "This is the best thing I've ever seen! And trust me, I've seen a lot. A whole lot.",
                Author = "Henrik",
                Email = "henrikn@microsoft.com"
            });
            Add(new Comment
            {
                ID = 2,
                Text = "Is this thing on? Because if it isn't on, we should really consider turning it on. Have you tried turning it on? I haven't. But you should consider it.",
                Author = "Eilon",
                Email = "elipton@microsoft.com"
            });
            Add(new Comment
            {
                ID = 3,
                Text = "My computer's cupholder doesn't work, can you help? I tried calling tech support, but they keep laughing and I don't understand why. It's really not helpful.",
                Author = "Glenn",
                Email = "gblock@microsoft.com"
            }); 
        }
        public IEnumerable<Comment> Get()
        {
            return comments.Values.OrderBy(c => c.ID);
        }
        public bool TryGet(int id, out Comment comment)
        {
            return comments.TryGetValue(id, out comment);
        }
        public Comment Add(Comment comment)
        {
            comment.ID = nextID++;
            comments[comment.ID] = comment;
            return comment;
        }
        public bool Delete(int id)
        {
            return comments.Remove(id);
        }
        public bool Update(Comment comment)
        {
            bool update = comments.ContainsKey(comment.ID);
            comments[comment.ID] = comment;
            return update;
        }
    }
}

 

右鍵"引用",在"管理NuGet"程序包中搜索、安裝Ninject。java

1

 

在ASP.NET Web API中,DefaultHttpControllerActivator默認使用DependencyResolver對象去激活目標HttpControlle,經過實現IDependencyResolver接口可自定義DependencyResolver,從而把Ninject引入。
jquery

using System;
using System.Collections.Generic;
using System.Web.Http.Dependencies;
using Ninject;
namespace MvcApplication5.Extension
{
    public class NinjectDependencyResolver : IDependencyResolver
    {
        private List<IDisposable> disposables = new List<IDisposable>();
        public IKernel Kernel { get; private set; }
        public NinjectDependencyResolver(NinjectDependencyResolver parent)
        {
            this.Kernel = parent.Kernel;
        }
        public NinjectDependencyResolver()
        {
            this.Kernel = new StandardKernel();
        }
        public void Register<TFrom, TTo>() where TTo : TFrom
        {
            this.Kernel.Bind<TFrom>().To<TTo>();
        }
        public IDependencyScope BeginScope()
        {
            return new NinjectDependencyResolver(this);
        }
        public object GetService(System.Type serviceType)
        {
            return this.Kernel.TryGet(serviceType);
        }
        public System.Collections.Generic.IEnumerable<object> GetServices(System.Type serviceType)
        {
            foreach (var service in this.Kernel.GetAll(serviceType))
            {
                this.AddDisposableService(service);
                yield return service;
            }
        }
        public void Dispose()
        {
            foreach (IDisposable disposable in disposables)
            {
                disposable.Dispose();
            }
        }
        private void AddDisposableService(object service)
        {
            IDisposable disposable = service as IDisposable;
            if (disposable != null && !disposables.Contains(disposable))
            {
                disposables.Add(disposable);
            }
        }
    }
}

 

在全局註冊NinjectControllerFactory這個自定義控制器工廠。web

 

        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            ......
            NinjectDependencyResolver dependencyResolver = new NinjectDependencyResolver();
            dependencyResolver.Register<ICommentRepository, CommentRepository>();
            GlobalConfiguration.Configuration.DependencyResolver = dependencyResolver; 
        }


建立名稱爲CommentsController空的API控制器,編寫以下:api

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using MvcApplication5.Models;
using MvcApplication5.Repository;
using Ninject;
namespace MvcApplication5.Controllers
{
    public class CommentsController : ApiController
    {
        [Inject]
        public ICommentRepository CommentRepository { get; set; }
        #region 獲取數據
        public IEnumerable<Comment> GetComments()
        {
            return CommentRepository.Get();
        }
        public Comment GetComment(int id)
        {
            Comment comment;
            if (!CommentRepository.TryGet(id, out comment))
            {
                throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound));
            }
            return comment;
        }
        #endregion
    }
}

 

在HomeController中提供一個Index視圖。app

 

using System.Web.Mvc;
namespace MvcApplication5.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }
    }
}

 

在Shared/_Layout.cshtml中:ide

 

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width" />
    <title>@ViewBag.Title</title>
    @Styles.Render("~/Content/css")
    <link href="~/Content/Demo.css" rel="stylesheet" />
</head>
<body>
    @RenderBody()
    @Scripts.Render("~/bundles/jquery")
    @RenderSection("scripts", required: false)
</body>

在Home/Index.cshtml視圖中,經過Knockout在頁面元素和頁面視圖模型間實現雙向綁定,經過jQuery把從後臺獲取到的集合賦值給前端的頁面視圖模型的comments字段,遍歷頁面視圖模型的comments,使用模版把內容顯示出來。
@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
<div>
    <button id="getComments">獲取評論</button>
</div>
<ul data-bind="template: { name: 'commentTemplate', foreach: comments }"> 
</ul> 
@section scripts
{
    <script src="~/Scripts/knockout-2.2.0.js"></script>
    <script type="text/javascript">
        viewModel = {
            comments: ko.observableArray([])
        };
        ko.applyBindings(viewModel);
        $(function() {
            $('#getComments').on("click", function() {
                viewModel.comments([]);
                $.get('/api/comments', function (data) {
                    viewModel.comments(data);
                });
            });
        });
    </script>
    <script id="commentTemplate" type="text/html">
        <li class="comment">
            <header>
                <div class="info">
                    <strong><span data-bind="text: Author"></span></strong>
                </div>
            </header>
            <div class="body">
                <p data-bind="text: Text"></p>
            </div>
        </li>
    </script>
}

2


參考資料:
http://www.cnblogs.com/artech/p/ioc-4-asp-net-web-api.html
https://code.msdn.microsoft.com/ASPNET-Web-API-JavaScript-d0d64dd7/sourcecode?

相關文章
相關標籤/搜索