Sudah pernah saya tulis sebelumnya tulisan membahas konsep dasar dari Dependency Injection di sini. Semoga pembaca bisa memahaminya dan siap untuk menerapkannya pada aplikasi yang dibuat. Sekarang pada tulisan ini pembaca akan belajar bagaimana menerapkan DI pada ASP.NET MVC 4 menggunakan Unity.
Pada MVC walaupun sudah ada pemisahan fungsi antara Model dan Controller namun Controller bergantung pada Model untuk mengeksekusi logika bisnis. Kode di bawah ini tidak akan asing lagi
1 2 3 4 5 6 7 8 9 10 |
public class BookController : Controller { private BookRepository _repository=new BookRepository(); public ActionResult Index() { var books=_repository.FindAll(); return View(_books); } } |
Terlihat kalau BookController bergantung pada BookRepository.
Artikel ini akan menjelaskan cara untuk men-decouple layer model pada layer controller dengan bantuan Unity.
Membuat Project
Langkah pertama buat projectnya terlebih dahulu. Di sini saya menggunakan Visual Studio 2013. Visual Studio 2012 juga gak akan bermasalah.
Instal Unity
Pasang Unity.Mvc4 pada project menggunakan Package Manager Console (Tools->Library Package Manager->Package Manager Console)
Bisa juga lewat GUI dengan cara klik kanan pada node project di Solution Explorer dan pilih Manage Nuget Pakcages.. kemudian search Unity.Mvc4 dan klik install.
Ketika sudah terpasang maka project akan memiliki 2 buah reference baru dan sebuah file baru dengan nama Bootstrapper.cs
Isi dari file Bootstrapper.cs seperti di bawah ini
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
using System.Web.Mvc; using Microsoft.Practices.Unity; using Unity.Mvc4; namespace MvcNunitDI { 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) { } } } |
Repository
Supaya sederhana maka pada repository saya hanya menggunakan in memory data. Nantinya repository ini yang akan di-inject ke controller.
Buat dahulu kelas modelnya pada folder Models
1 2 3 4 5 6 7 8 9 10 |
namespace MvcNunitDI.Models { public class Book { public int Id { get; set; } public string Title { get; set; } public string Author { get; set; } public decimal Price { get; set; } } } |
Tambahkan interface IBookRepository pada folder Repository (buat terlebih dahulu folder ini)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
using MvcNunitDI.Models; using System.Collections.Generic; namespace MvcNunitDI.Repository { public interface IBookRepository { List<Book> FindAll(); Book Find(int id); void Save(Book book); void Update(Book book); void Delete(int id); } } |
Buat sekalian implementasinya BookRepository
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
using MvcNunitDI.Models; using System.Collections.Generic; using System.Linq; namespace MvcNunitDI.Repository { public class BookRepository : IBookRepository { private int _nextId = 4; private static List<Book> _books = new List<Book>() { new Book(){Id=1,Title="Blink",Author="Malcom Gladwell",Price=50.00M}, new Book(){Id=2,Title="Clutch",Author="Sullivan",Price=48.00M}, new Book(){Id=3,Title="Super",Author="Metatron",Price=45.00M}, }; public List<Models.Book> FindAll() { return _books; } public Models.Book Find(int id) { return _books.SingleOrDefault(b => b.Id == id); } public void Save(Models.Book book) { book.Id = _nextId; _nextId += 1; _books.Add(book); } public void Update(Models.Book book) { var bookToUpdate = _books.SingleOrDefault(b => b.Id == book.Id); bookToUpdate.Title = book.Title; bookToUpdate.Author = book.Author; bookToUpdate.Price = book.Price; } public void Delete(int id) { var bookToRemove=_books.SingleOrDefault(b=>b.Id==id); _books.Remove(bookToRemove); } } } |
Register Dependency
Supaya repository dapat di-inject ke dalam controller maka kita perlu mendaftarkannya terlebih dahulu pada file Bootstrapper.cs tadi. Tambahkan sebaris kode yang saya tandai di bawah ini
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
using System.Web.Mvc; using Microsoft.Practices.Unity; using Unity.Mvc4; using MvcNunitDI.Repository; namespace MvcNunitDI { 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(); container.RegisterType<IBookRepository, BookRepository>(); RegisterTypes(container); return container; } public static void RegisterTypes(IUnityContainer container) { } } } |
Inject Repository ke Controller
Sekarang kita sudah siap untuk meng-inject repository ke dalam controller menggunakan constructor injection.
Buat kelas BookController pada folder Controllers
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
using MvcNunitDI.Repository; using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace MvcNunitDI.Controllers { public class BookController : Controller { private IBookRepository bookRepository; public BookController(IBookRepository repository) { this.bookRepository = repository; } public ActionResult Index() { var books = bookRepository.FindAll(); return View(books); } } } |
Setting Global.asax.cs
Langkah terakhir supaya DI dapat berjalan adalah menginisialiasi Bootstrapper tadi dengan cara menambahkan sebaris kode yang saya tandai ini pada file Global.asax.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Http; using System.Web.Mvc; using System.Web.Optimization; using System.Web.Routing; namespace MvcNunitDI { public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { AreaRegistration.RegisterAllAreas(); WebApiConfig.Register(GlobalConfiguration.Configuration); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); Bootstrapper.Initialise(); } } } |
Jalankan
Running aplikasi dan see how everything is good, running well 😀