Frameworklerin yeni versiyonlarında sıklıkla mevcut bileşenler tekrar kullanılabilirlik açısından ele alınır ve iyileştirmeler yapılır. ASP.NET 5 ve ASP.NET MVC 6.0 ile partial view ve child action özellikleri ele alınıp view components ile daha tekrar kullanılabilir hale getirilmiş. Tekrar kullanılabilir bir taslak yaratmak için controller'a bağımlılık ortadan kaldırılmış ve asenkron olarak kullanabilme sağlanmış. Bu yazımda öncelikle child action ile tekrar kullanılabilir bir görsel taslak hazırlamaya çalışıp, sonra bu örneği view components ile hazırlayıp kullanmaya çalışacağız.
ASP.NET MVC 2 Child Actions ile tekrar kullanılabilir bileşenler
Child Actions konusuna hakim okuyucular bu bölümü atlayıp bir sonraki bölüme devam edebilir. ASP.NET MVC 2 ile gelen Child Actions sayesinde controllerlarımıza tanımladığımız aksiyonları ChildActionOnly attribute'u ile işaretleyip, istediğimiz görsel taslak içerisinde çağırabiliyoruz. Böylece DRY prensibine uygun olarak aksiyonu ve görselini uygulamamız içerisinde defalarca kullanabiliyoruz. Aşağıda child action olarak tanımladığımız bir aksiyonu ve görsel taslağını inceleyebiliriz :
public class HomeController : Controller
{
public ActionResult Contact()
{
return View();
}
[ChildActionOnly]
public ActionResult Movies()
{
List<Movie> movieList = new List<Movie>();
movieList.Add(new Movie() { ImdbId = "tt0470752", Name = "Ex Machina" });
movieList.Add(new Movie() { ImdbId = "tt2562232", Name = "Birdman" });
movieList.Add(new Movie() { ImdbId = "tt0137523", Name = "Fight Club" });
return View(movieList);
}
}
Görsel taslak dosyası : Movies.cshtml
@model List<ViewComponentsTrial.Models.Movie>
<div>Movies : </div>
<ul>
@foreach(var item in Model) {
<li><a href="http://www.imdb.com/title/@item.ImdbId">@item.Name</a></li>
}
</ul>
Yukarıda hazırlamış olduğumuz tekrar kullanılabilir child action örneğini uygulamamız içerisinde aşağıdaki gibi kullanabiliyoruz :
@Html.Action("Movies")
View Component'in Hazırlanması ve Kullanılması
Yukarıdaki örnekte child action yardımı ile hazırladığımız film listesini, uygulamamız genelinde kullanılabilecek bir View Component olarak hazırlamak istersek aşağıdaki gibi ViewComponent sınıfından türeyen bir sınıf hazırlamamız gerekiyor.
public class MoviesViewComponent : ViewComponent
{
public IViewComponentResult Invoke(string imdbId)
{
List<Movie> movies = GetMovies();
if (string.IsNullOrEmpty(imdbId))
{
return View(GetMovies());
}
else
{
return View(GetMovies().Where(m => m.ImdbId == imdbId));
}
}
public List<Movie> GetMovies()
{
List<Movie> movieList = new List<Movie>();
movieList.Add(new Movie() { ImdbId = "tt0470752", Name = "Ex Machina" });
movieList.Add(new Movie() { ImdbId = "tt2562232", Name = "Birdman" });
movieList.Add(new Movie() { ImdbId = "tt0137523", Name = "Fight Club" });
return movieList;
}
}
View Component olarak hazırladığımız sınıfların isminin ViewComponent şeklinde bitmesi gerekiyor. View component'imiz Invoke metodu ile görsel taslakta kullanılacak modeli dönüyor. Hazırladığımız view component'in görsel taslağını aşağıdaki gibi hazırlıyoruz. Burada dikkat edilmesi gereken nokta, görsel taslağın konumlandığı dizin. Görsel taslağımız ~\Views\Shared\Components\Movies dizininde bulunuyor. Yani kullanılmak istenen controller'ın sahip olduğu görsel taslak dizininin altında Components dizini oluşturup bunun altına view componentimiz için bir dizin oluşturmamız gerekiyor. Bu dizinde görsel taslağımızı Default.isml ismi ile kaydediyoruz. Ben örnek olarak kullandığım view component'i tüm görsel taslaklarda kullanabilmek için shared dizini altına konumlandırdım. Dilersek view component diğer dizinler altına konumlanıp sadece konumlandığı dizin altında kullanılması da sağlanabilir. Görsel taslağımıza göz atarsak :
@model IEnumerable<ASP_NET_5_TagHelpers.Models.Movie>
<div>Movies : </div>
<ul>
@foreach (var item in Model)
{
<li><a href="http://www.imdb.com/title/@item.ImdbId">@item.Name</a></li>
}
</ul>
Şimdi hazırladığımız view component'i kullanmak için yapmamız gereken tek şey sayfalarımızda aşağıdaki gibi çağırmak :
@Component.Invoke("Movies", "")
// Asenkron kullanım :
@await Component.InvokeAsync("Movies", "")
// Parametreli kullanım :
@await Component.InvokeAsync("Movies", "tt2562232")
Sonuç
View components, ASP.NET içerisindeki görsel taslakları yeniden kullanılabilir yapmak için getirilmiş ve önceki tekniklere göre çok daha etkili bir teknik. Sadece controller bağlantısının koparılması bile tekrar kullanılabilirlik açısından tercih sebebi olmasını sağlayacaktır. Örneğimde yer alan kod bloklarına ve dosyalara aşağıdaki github projesi ile ulaşabilirsiniz :
View Components Örnekleri