In this case, it seems that the parameter that needs to be created (CustomProfile) should be taken from the session. Then you can use a specific connecting device for the company model, which comes from the default connecting object, changing only the method of creating an instance of the Company class (it will then fill in the properties in the same way as by default):
public class CompanyModelBinder: DefaultModelBinder { private const string sessionKey = "CustomProfile"; protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType) { if(modelType == typeOf(Company)) { var customProfile = (CustomProfile) controllerContext.HttpContext.Session[sessionKey];
You register this binder only for the type of company by adding it to the global.asax Application_Start method:
ModelBinders.Binders.Add(typeOf(Company), CompanyModelBinder);
Another option would be to create a dependency model using Ninject dependencies, inheriting from DefaultModelBinder (since you use Ninject, it knows how to instantiate specific types without having to register them). However, you will need to set up a custom method that creates a CustomProfile in a Ninject, which I assume you can use with ToMethod (). To do this, you will extract the extraction of your Ninject kernel configuration outside the factory controller:
public static class NinjectBootStrapper{ public static IKernel GetKernel() { IKernel ninjectKernel = new StandardKernel(); AddBindings(ninjectKernel); } private void AddBindings(IKernel ninjectKernel) { ninjectKernel.Bind<IAuthProvider>().To<FormsAuthProvider>(); ninjectKernel.Bind<IMembershipProvider>().To<MembershipProvider>(); ninjectKernel.Bind<ICustomProfileProvider>().To<CustomProfileProvider>(); ninjectKernel.Bind<ICompanyProvider>().To<CompanyProvider>(); ninjectKernel.Bind<CustomProfile>().ToMethod(context => ); } } public class NinjectControllerFactory : DefaultControllerFactory { private readonly IKernel ninjectKernel; public NinjectControllerFactory(IKernel kernel) { ninjectKernel = kernel; } protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType) { return controllerType == null ? null : (IController) ninjectKernel.Get(controllerType); } }
In this case, you will create this connecting device:
public class NinjectModelBinder: DefaultModelBinder { private readonly IKernel ninjectKernel; public NinjectModelBinder(IKernel kernel) { ninjectKernel = kernel; } protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType) { return ninjectKernel.Get(modelType) ?? base.CreateModel(controllerContext, bindingContext, modelType) } }
And you should update global.asax as:
IKernel kernel = NinjectBootStrapper.GetKernel(); ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory(kernel)); ModelBinders.Binders.DefaultBinder = new NinjectModelBinder(kernel);