Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Register a custom model binder with Sharp Architecture

I'm new to MVC (I'm using ver. 3) and Sharp Architecture, and I'm having trouble figuring out how to use a custom model binder.

I have a domain object (not a view model) called Teacher, and a repository ITeacherRepository done in the standard Sharp Architecture way. I register this route:

            routes.MapRoute(
            "Teacher",
            "Teacher/{tid}/{action}",
            new { controller = "Teacher", action = "Index" });

and the Index method on TeacherController looks like this:

        public ActionResult Index(int tid)
    {
        Teacher t = TeacherRepository.Get(tid);
        if (t == null)
            throw new InvalidOperationException("No such teacher");

        TeacherDisplay display = new TeacherDisplay(t);
        return View("Index", display);
    }

That all works fine. Now I want to take the next step, and implement a custom model binder for Teacher so the controller method can look like this:

        public ActionResult Index(Teacher t)
    {
        if (t == null)
            throw new InvalidOperationException("No such teacher");

        TeacherDisplay display = new TeacherDisplay(t);
        return View("Index", display);
    }

I wrote a primitive model binder:

public class TeacherBinder : SharpArch.Web.ModelBinder.SharpModelBinder
{
    private ITeacherRepository teacherRepository = null;

    public TeacherBinder(ITeacherRepository repo)
    {
        this.teacherRepository = repo;
    }

    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        int tid = (int)bindingContext.ValueProvider.GetValue("tid").ConvertTo(typeof(Int32));

        Teacher t = teacherRepository.Get(tid);
        return t;
    }
}

And now I'm stuck. How do I properly register this in a Sharp Architecture project? I assume I have to plug this into the Castle Windsor configuration, too. Should I have an interface ITeacherBinder as well, and register that with Windsor?

EDIT

To clarify my problem: I can't figure out how to register my model binder so that the MVC framework will instantiate it through Windsor, and therefore take care of passing the required constructor argument. Controllers are instantiated by Windsor, and this is hooked up by this line in global.asax.cs:

 ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory(container));

I don't see an equivalent model builder factory.

like image 925
Carl Raymond Avatar asked Dec 27 '22 21:12

Carl Raymond


1 Answers

One way to register is by adding below line in Application_Start method in Global.asax

ModelBinders.Binders.Add(typeof(Teacher), new TeacherModelBinder());

This http://www.dominicpettifer.co.uk/Blog/39/dependency-injection-in-asp-net-mvc-2---part-2--modelbinders-viewmodels describes different way of doing it.

To do through Castle Windsor, you can add below code to ComponentRegistrar.cs (located in CastleWindsor folder)

container.Register(AllTypes.Of() .FromAssembly(typeof(TeacherBinder).Assembly) .Configure(c => c.LifeStyle.Singleton.Named( c.Implementation.Name.ToLower())));

like image 136
hgirish Avatar answered Jan 18 '23 06:01

hgirish