Skip to content
Browse files

Adding CategoriesActionFilter

  • Loading branch information...
1 parent c9b3882 commit 5e638d21c290f9ec36f8f8625f80807356f778b7 @jchadwick jchadwick committed Jan 24, 2012
View
14 Core/Model/Category.cs
@@ -6,9 +6,18 @@ namespace Ebuy
[MetadataType(typeof(Category.Metadata))]
public class Category : Entity<long>
{
+ public virtual ICollection<Auction> Auctions { get; set; }
+
+ public bool IsTopLevelCategory
+ {
+ get { return ParentId == null; }
+ }
+
public string Name { get; set; }
- public virtual ICollection<Auction> Auctions { get; set; }
+ public long? ParentId { get; set; }
+
+ public virtual Category Parent { get; set; }
public virtual ICollection<Category> SubCategories { get; set; }
@@ -36,6 +45,9 @@ public class Metadata
{
[Required, StringLength(100)]
public object Name;
+
+ [ForeignKey("Parent")]
+ public object ParentId;
}
}
}
View
46 Website/ActionFilters/CategoriesActionFilter.cs
@@ -0,0 +1,46 @@
+using System;
+using System.Linq;
+using System.Web.Mvc;
+using AutoMapper;
+using Ebuy.DataAccess;
+using Ebuy.Website.Models;
+
+namespace Ebuy.Website.ActionFilters
+{
+ public class CategoriesActionFilter : IActionFilter
+ {
+ private readonly Func<IRepository> _repositoryFactory;
+
+ // Default constructor for ease of initialization
+ public CategoriesActionFilter()
+ : this(() => DependencyResolver.Current.GetService<IRepository>())
+ {
+ }
+
+ // Constructor injection for testing purposes
+ public CategoriesActionFilter(Func<IRepository> repositoryFactory)
+ {
+ _repositoryFactory = repositoryFactory;
+ }
+
+
+ public void OnActionExecuting(ActionExecutingContext filterContext)
+ {
+ var viewBag = filterContext.Controller.ViewBag;
+
+ // If the Categories have already been loaded, don't load them again
+ if (viewBag.Categories != null)
+ return;
+
+ // Get all top-level categories
+ var categories = _repositoryFactory().Query<Category>(cat => cat.ParentId == null);
+
+ viewBag.Categories = categories.Select(Mapper.DynamicMap<CategoryViewModel>).ToArray();
+ }
+
+ public void OnActionExecuted(ActionExecutedContext filterContext)
+ {
+ // Nothing
+ }
+ }
+}
View
4 Website/App_Start/Filters.cs
@@ -1,7 +1,8 @@
using System.Web.Mvc;
+using Ebuy.Website.ActionFilters;
using Ebuy.Website.App_Start;
-[assembly: WebActivator.PreApplicationStartMethod(typeof(Filters), "Start")]
+[assembly: WebActivator.PostApplicationStartMethod(typeof(Filters), "Start")]
namespace Ebuy.Website.App_Start
{
@@ -15,6 +16,7 @@ public static void Start()
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute());
+ filters.Add(new CategoriesActionFilter());
}
}
}
View
8 Website/App_Start/NinjectMVC3.cs
@@ -57,14 +57,16 @@ public class BindingsModule : Ninject.Modules.NinjectModule
{
public override void Load()
{
- Bind<ControllerActions>().ToMethod(x => ControllerActions.DiscoverControllerActions()).InSingletonScope();
+ Bind<ControllerActions>()
+ .ToMethod(x => ControllerActions.DiscoverControllerActions())
+ .InSingletonScope();
- Bind<IRouteGenerator>().To<RouteGenerator>();
+ Bind<IRouteGenerator>().To<RouteGenerator>().InSingletonScope();
Bind<DataContext>().ToSelf().InRequestScope()
.OnDeactivation(x => x.SaveChanges());
- Bind<IRepository>().To<Repository>()
+ Bind<IRepository>().To<Repository>().InRequestScope()
.WithConstructorArgument("isSharedContext", true);
}
}
View
8 Website/Controllers/HomeController.cs
@@ -17,11 +17,13 @@ public HomeController(IRepository repository)
public ActionResult Index()
{
- var categories = _repository.All<Category>();
+ ViewBag.TestValue = "Test value!";
+
+ var categories = _repository.Query<Category>(cat => cat.ParentId == null);
var viewModel = new HomepageViewModel {
- Categories = categories.Select(Mapper.DynamicMap<CategoryViewModel>),
- };
+ Categories = categories.Select(Mapper.DynamicMap<CategoryViewModel>),
+ };
return View("Homepage", viewModel);
}
View
1 Website/Ebuy.Website.csproj
@@ -127,6 +127,7 @@
</Reference>
</ItemGroup>
<ItemGroup>
+ <Compile Include="ActionFilters\CategoriesActionFilter.cs" />
<Compile Include="App_Start\Areas.cs" />
<Compile Include="App_Start\InitializeMembership.cs" />
<Compile Include="App_Start\ModelBinding.cs" />
View
7 Website/Extensions/UrlHelperExtensions.cs
@@ -7,9 +7,14 @@ namespace Ebuy.Website.Extensions
public static class UrlHelperExtensions
{
+ public static string Category(this UrlHelper helper, string categoryKey)
+ {
+ return helper.Action("Category", "Auctions", new { key = categoryKey });
+ }
+
public static string Category(this UrlHelper helper, CategoryViewModel category)
{
- return helper.Action("Category", "Auctions", new { key = category.Key });
+ return Category(helper, category.Key);
}
public static string Auction(this UrlHelper helper, Auction auction)
View
18 Website/Models/CategoryViewModel.cs
@@ -1,12 +1,28 @@
+using System.Collections.Generic;
+using System.Linq;
+
namespace Ebuy.Website.Models
{
public class CategoryViewModel
{
+ public int AuctionsCount { get; set; }
+
+ public bool HasSubCategories
+ {
+ get
+ {
+ return SubCategories != null
+ && SubCategories.Any();
+ }
+ }
+
public string Key { get; set; }
public string Name { get; set; }
- public int AuctionsCount { get; set; }
+ public bool IsTopLevelCategory { get; set; }
+
+ public IEnumerable<CategoryViewModel> SubCategories { get; set; }
}
}
View
6 Website/Views/Home/Homepage.cshtml
@@ -31,14 +31,16 @@
</section>
<nav>
<ul id="menu">
- <li>@Html.ActionLink("Auctions", "Index", "Auctions")</li>
+ @foreach (CategoryViewModel category in ViewBag.Categories) {
+ <li><a href="@Url.Category(category.Key)">@category.Name</a></li>
+ }
</ul>
</nav>
</div>
</div>
</header>
<div id="body">
-
+ <h1>@ViewBag.TestValue</h1>
<section class="welcome-banner">
<div id="categories-container">
View
4 Website/Views/Shared/_Layout.cshtml
@@ -32,7 +32,9 @@
</section>
<nav>
<ul id="menu">
- <li>@Html.ActionLink("Auctions", "Index", "Auctions")</li>
+ @foreach (CategoryViewModel category in ViewBag.Categories) {
+ <li><a href="@Url.Category(category.Key)">@category.Name</a></li>
+ }
</ul>
</nav>
</div>
View
6 Website/Views/Shared/_Layout.mobile.cshtml
@@ -30,9 +30,9 @@
</section>
<nav>
<ul id="menu" data-role="header">
- <li>@Html.ActionLink("Home", "Index", "Home")</li>
- <li>@Html.ActionLink("About", "About", "Home")</li>
- <li>@Html.ActionLink("Contact", "Contact", "Home")</li>
+ @foreach (CategoryViewModel category in ViewBag.Categories) {
+ <li><a href="@Url.Category(category.Key)">@category.Name</a></li>
+ }
</ul>
</nav>
</div>

0 comments on commit 5e638d2

Please sign in to comment.
Something went wrong with that request. Please try again.