Bagian 1 dari posting ini menjelaskan tentang pemisahan antara Model dengan View-Controller dalam project yang berbeda dalam satu solusi ASP.NET MVC. Di bagian 2 ini kita akan main-main lebih lanjut dengan bagian Model dengan menerapkan satu pattern yang cukup terkenal dalam industri software yaitu Repository pattern. Teori dari pattern ini bisa dibaca lebih lanjut dalam bukunya Martin Fowler yang berjudul Pattern of Enterprise Application Architecture (PoEAA). Saya tidak akan membeberkan teorinya, namun akan bercerita singkat saja tentang penggunaan pattern ini, khususnya di solusi ASP.NET MVC.
Secara gampangnya repository adalah mekanisme untuk menyimpan data lengkap dengan method-method selector yang memudahkan kita meng-query data dari repository tersebut. Misalnya kita punya repository bernama EmployeeRepository, maka kita bisa memiliki method-method selector berikut ini:
- GetEmployeeById
- GetEmployeeByName
- GetEmployeeBySupervisor
Contohnya kalau aplikasi kita meng-query data employee berdasarkan name, maka aplikasi kita akan memanggil EmployeeRepository.GetEmployeeByName("Agus Suhanto"). Aplikasi tidak perlu tahu bagaimana si repository menyimpan dan memfilter data. Yang perlu diketahui oleh aplikasi adalah method-method yang di 'publish' oleh repository tersebut, yang biasanya available dalam bentuk interface. Dengan menerapkan repository pattern, berarti kita juga melakukan decoupling antara aplikasi dengan underlying data query mechanism.
So, mari kita terapkan Repository pattern ini dalam sebuah project ASP.NET MVC. Untuk keperluan tersebut saya akan menggunakan model database seperti dalam gambar berikut ini.
Saya akan memfokuskan perhatian kepada dua entity yang diberi kotak warna merah yaitu News dan Page. Kedua entity tersebut akan dibuatkan repository model-nya dan ditempakan dalam project Models dalam solusi ASP.NET MVC. Underlying data mechanism yang saya pakai adalah ADO.NET Entity Framework. Oleh karena itu langkah pertama yang saya lakukan adalah meng-generate model Entity Framework dan memasukkannya dalam folder Entities. (Perhatikan gambar susunan folder dari project Models dalam solusi ASP.NET MVC berikut ini).
Entities (termasuk class-class yang di-generate oleh ADO.NET Entity Framework) saya tempatkan dalam folder Entities (diberi kotak warna hijau). Sedangkan Repositories saya tempatkan dalam folder Repositories (diberi kotak warna orange).
Berikut ini sample source code untuk repositories, saya ambikan untuk interface INewsRepository dan class NewsRepositories.
// Copyright (C) 2009 by Agus Suhanto [agus.suhanto@mvps.org]
// For more information please visit http://suhanto.com
//
#region
using System.Collections.Generic;
using CompanyProfile.Models.Entities;
using CompanyProfile.Models.Helpers;
#endregion
namespace CompanyProfile.Models.Repositories
{
public interface INewsRepository
{
IList<News> GetLatestNews(string cultureId, int latestNewsCount);
IPagedList<News> GetAllNews(string cultureId, int pageIndex, int pageSize);
News GetNewsByName(string cultureId, string name);
}
}
// Copyright (C) 2009 by Agus Suhanto [agus.suhanto@mvps.org]
// For more information please visit http://suhanto.com
//
#region
using System.Collections.Generic;
using System.Linq;
using CompanyProfile.Models.Entities;
using CompanyProfile.Models.Helpers;
#endregion
namespace CompanyProfile.Models.Repositories.Impl
{
public class NewsRepository : INewsRepository
{
private readonly CompanyEntities entities;
public NewsRepository(CompanyEntities entities)
{
this.entities = entities;
}
#region INewsRepository Members
public IList<News> GetLatestNews(string cultureId, int latestNewsCount)
{
return
(from n in entities.News
where n.CultureId == cultureId && n.Status == Constants.Published
select n).Take(latestNewsCount).ToList();
}
public IPagedList<News> GetAllNews(string cultureId, int pageIndex, int pageSize)
{
return (from n in entities.News
where n.CultureId == cultureId && n.Status == Constants.Published
orderby n.NewsDate descending
select n).ToPagedList(pageIndex, pageSize);
}
public News GetNewsByName(string cultureId, string name)
{
return (from n in entities.News
where n.CultureId == cultureId && n.Name == name
select n).FirstOrDefault();
}
#endregion
}
}
Repositories yang saya buat tadi bisa langsung di-consume oleh Controllers dalam project ASP.NET MVC kita. Namun instead of memakainya langsung dalam Controllers, saya akan menghadirkan layer berikutnya berupa Service Layers yang akan menjadi jembatan antara Repositories dan Controllers. Pembahasan mengenai Service Layers ini akan saya masukkan dalam posting berikutnya (ke 3).
Oke, semoga penjelasan singkat mengenai pemakaian Repository pattern dalam project ASP.NET MVC bermanfaat.