简体   繁体   中英

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.

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())));

I'm not familiar with what S#arp architecture provides in this case, but you can do something like this: http://iridescence.no/post/Constructor-Injection-for-ASPNET-MVC-Model-Binders.aspx .

Then you just register all your binders in container, and register this new binder resolver as default model binder in asp.net mvc.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM