Skip to content

Instantly share code, notes, and snippets.

@ToJans
Created January 18, 2010 20:15
Show Gist options
  • Save ToJans/280330 to your computer and use it in GitHub Desktop.
Save ToJans/280330 to your computer and use it in GitHub Desktop.
By referencing the MvcExtensions.DLL in an asp.net MVC app you get a decent an fully working MVC app with just a few pieces of code
// This is a preview of my future MVCExtensions release
// By referencing the MvcExtensions.DLL in an asp.net MVC app you get a decent an fully working MVC app with just a few pieces of code
// It returns a working FluentNHibernate ORM,spark viewengine with "al_a" and "al_form" html tags included
// (for removing controller dependencies from the viewmodel),
// a custom automapper and the possibility to setup custom ioc child container per view
//
// Let me know what you think
// www.corebvba.be
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
// setup MVC extensions
// get your db mappings(specific for project)
var mappings = new TaskDatabaseFluentMapping();
// assign the mappings to the module using a SqLiteInMemoryDatabase
var module = new MvcExtensionsModule();
module.Register(new SqlLiteInMemoryDatabase(mappings));
// register custom IOC childcontainer for HomeController
module.Container.Register(
Component.For<IMvcCustomContainer<HomeController>>().ImplementedBy<HomeContainer>().LifeStyle.Transient
);
// set the namespace where the controllers can be found
ControllerBuilder.Current.DefaultNamespaces.Add("Tasks.Core.Controllers");
}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>
<use content="Title" />
</title>
</head>
<body>
<use content="Main" />
</body>
</html>
<viewdata model="Tasks.UI.ViewModels.Home.VMEdit" />
<content name="Title">
Edit
</content>
<content name="Main">
<h3>Edit this task</h3>
<al_form al="Model.AL_PostEdit">
<label for="Name">Name :</label><br/>
<input type="text" value="${Model.Name}" name="Name" /><br/>
<label for="Description">Description:</label><br/>
<textarea cols="20" rows="2" name="Description" >${Model.Description}</textarea><br />
</al_form>
<al_a al="Model.AL_CancelEdit" />
</content>
// this child container is used to construct the controller
// it uses a custom automapper to map the domain model to the viewmodels
public class HomeContainer : MvcContainer, IMvcCustomContainer<HomeController>
{
public HomeContainer()
{
AddComponentLifeStyle<IMapper,MyMapper>(LifestyleType.Singleton);
}
class MyMapper : MvcMapper
{
HomeController cHome=null;
public override void Initialize()
{
// map viewmodels
MapperCfg.CreateMap<Task, VMIndex.Task>()
.ForMember(v => v.Name, m => m.MapFrom(t => t.Name))
.ForMember(v => v.Description, m => m.MapFrom(t => t.Description))
.ForMember(v => v.AL_Status, m => m.MapFrom(t => cHome.AL(t.Done ? "Done" : "Todo", a => a.Done(t.Id))))
.ForMember(v => v.AL_Edit, m => m.MapFrom(t => cHome.AL("Edit", a => a.Edit(t.Id))))
.ForMember(v => v.AL_Delete, m => m.MapFrom(t => cHome.AL("Delete", a => a.Delete(t.Id))));
MapperCfg.CreateMap<Task[], VMIndex>()
.ForMember(v => v.AllTasks, m => m.MapFrom(t => t))
.ForMember(v => v.HasNoTasks, m => m.MapFrom(t => t.Length == 0))
.ForMember(v => v.AL_AddTask, m => m.MapFrom(t => cHome.AL("Add new task", c => c.AddNewTask(null))));
MapperCfg.CreateMap<Task, VMEdit>()
.ForMember(v => v.Name, m => m.MapFrom(t => t.Name))
.ForMember(v => v.Description, m => m.MapFrom(t => t.Description))
.ForMember(v => v.AL_CancelEdit, m => m.MapFrom(t => cHome.AL("Cancel changes", c => c.Index())))
.ForMember(v => v.AL_PostEdit, m => m.MapFrom(t => cHome.AL("Save changes", c => c.PostEdit(t.Id))));
}
}
}
// this is the controller code for a fully functional tasklist
public class HomeController : Controller
{
IMapper sMap;
IRepository sRepo;
IUnitOfWork sUnitOfWork;
public HomeController(IMapper sMap,IRepository sRepo,IUnitOfWork sUnitOfWork)
{
this.sMap = sMap;
this.sRepo = sRepo;
this.sUnitOfWork = sUnitOfWork;
}
public ActionResult Index()
{
var tasks = sRepo.Find<Task>().ToArray();
return View(sMap.To<VMIndex>().From(tasks));
}
public ActionResult AddNewTask(Task task)
{
TryUpdateModel(task);
sRepo.SaveOrUpdate(task);
sUnitOfWork.Commit();
return this.RedirectToAction(c => c.Index());
}
public ActionResult Done(int id)
{
var task = sRepo.GetById<Task>(id);
task.Done = !task.Done;
sRepo.SaveOrUpdate(task);
sUnitOfWork.Commit();
return this.RedirectToAction(c=>c.Index());
}
public ActionResult Edit(int id)
{
var task = sRepo.GetById<Task>(id);
return View(sMap.To<VMEdit>().From(task));
}
public ActionResult PostEdit(int id)
{
var task = sRepo.GetById<Task>(id);
UpdateModel(task);
sRepo.SaveOrUpdate(task);
sUnitOfWork.Commit();
return this.RedirectToAction(c => c.Index());
}
public ActionResult Delete(int id)
{
var task = sRepo.GetById<Task>(id);
sRepo.Delete(task);
sUnitOfWork.Commit();
return this.RedirectToAction(c => c.Index());
}
}
<viewdata model="Tasks.UI.ViewModels.Home.VMIndex" />
<content name="Title">
Index
</content>
<content name="Main">
<h1>Task list</h1>
<if condition="Model.HasNoTasks">
No tasks yet.
</if>
<else>
<table>
<tr>
<td>Name</td>
<td>Description</td>
<td>Status</td>
<td>Edit</td>
<td>Delete</td>
</tr>
<tr each="var t in Model.AllTasks">
<td>${t.Name}</td>
<td>${t.Description}</td>
<td><al_a al="t.AL_Status" /></td>
<td><al_a al="t.AL_Edit" /> </td>
<td><al_a al="t.AL_Delete" /> </td>
</tr>
</table>
</else>
<hr />
<h3>Add a new task</h3>
<al_form al="Model.AL_AddTask">
<label for="Name">Name :</label><br />
<input type="text" name="Name" /><br />
<label for="Description">Description:</label><br />
<textarea cols="20" rows="2" name="Description" ></textarea><br />
</al_form>
</content>
// the model itself
public class Task : IModelId
{
public virtual int Id { get; set; }
public virtual String1024 Name { get; set; }
public virtual Memo Description { get; set; }
public virtual bool Done { get; set; }
}
// Map the database : This is all the code you need to implement to have a fully functional database/persistence layer
public class TaskDatabaseFluentMapping : IFluentMapping
{
// More info : http://wiki.fluentnhibernate.org/Auto_mapping
public AutoPersistenceModel Map()
{
return AutoMap.AssemblyOf<Model.Task>(t => t.Namespace == typeof(Model.Task).Namespace);
}
//
}
// viewmodel for the edit.spark page
public class VMEdit
{
public string Name;
public string Description;
public VMActionLink AL_PostEdit;
public VMActionLink AL_CancelEdit;
}
// viewmodel for the index.spark page
public class VMIndex
{
public class Task
{
public string Name;
public string Description;
public VMActionLink AL_Status;
public VMActionLink AL_Edit;
public VMActionLink AL_Delete;
}
public IEnumerable<Task> AllTasks;
public VMActionLink AL_AddTask;
public bool HasNoTasks;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment