Following my last post on the DictionaryAdapter, I’ll demonstrate here how you can get typed access to your views’ properties.
What it requires from you:
Declare an interface for each of your views. That is a Good Thing anyway, as designing to a contract is a good best practice, and it allows for easy testing.
Have a base class for your controller that would define TypedFlash and TypedPropertyBag. Not mandatory, but very convenient.
Use the newest build of AspView. Again - not mandatory, but helpful.
Now for the showtime.
First we would create a base class for our controllers, with a TypedPropertyBag and TypedFlash properties:
public abstract class Controller<IView> : SmartDispatcherControllerController where IView : class{ IDictionaryAdapterFactory dictionaryAdapterFactory; IView typedPropertyBag; IView typedFlash; protected IView TypedPropertyBag { get { if (typedPropertyBag == null) typedPropertyBag = dictionaryAdapterFactory.GetAdapter<IView>(PropertyBag); return typedPropertyBag; } } protected IView TypedFlash { get { if (typedFlash == null) typedFlash = dictionaryAdapterFactory.GetAdapter<IView>(Flash); return typedFlash; } } protected override void Initialize() { base.Initialize(); IDictionaryAdapterFactory dictionaryAdapterFactory = new DictionaryAdapterFactory(); }}
tip:
You can look at a more complete version of that base-class, written by Lee Henson (who have made some improvements to the original DictionaryAdapter, and also have introduced me to Peroni Beer).The base controller also declares a type parameter for a Session DictionaryAdapter, hooks into the Castle.Tools.CodeGenerator, and uses IoC for DI.Talking about those issues is a separate subject, for other posts.
Now let’s create the view contract. A rather stupid example would be:
public interface IStupidView{ Guid Id { get; set; } string Name { get; set; }}
controller:
public class StupidController : Controller<IStupidView>{ public void Index() { } public void DoStuff(string name, string password) { if (password != "AspView Rocks") { TypedFlash.Name = name; TypedFlash.Message = "Wrong Password"; RedirectToAction("Index"); return; } TypedPropertyBag.Id = Guid.NewGuid(); TypedPropertyBag.Name = name; }}
view (Index.aspx):
<%@ Page Language="C#" Inherits="Castle.MonoRail.Views.AspView.ViewAtDesignTime<IStupidView>" %><%%><p><%=view.Message %></p><form action="DoStuff.rails">Name: <input type="text" name="name" value="<%= view.Name %>" /> <br />password: <input type="password" name="password" /> <br /><input type="submit" /></form>
view (DoStuff.aspx):
<%@ Page Language="C#" Inherits="Castle.MonoRail.Views.AspView.ViewAtDesignTime<IStupidView>" %><%%>The data was: <br />Id: <%= view.Id %>, Name: <%= view.Name %>
Look at the intellisense (and at my ultra-cool black color scheme):
Things to notice:
view (Index.aspx):
<aspview ... >... <reference assembly="AspViewTestSite.dll"/>...</aspview>
...<% IMyViewContract view = new Castle.Components.DictionaryAdapter.DictionaryAdapterFactory() .GetAdapter<IMyViewContract>(Properties); %>...blah blah <%=view.UsefulProperty %>...
Ok, cut the crap. where can I get it?
UPDATE:
The DictionaryAdapter was initially written by the guys from Eleutian as part of Castle.Tools.CodeGenerator.