在这种情况下,您需要创建的参数(CustomProfile)似乎必须从会话中获取。然后,您可以为从默认模型绑定程序派生的 Company 模型使用特定的模型绑定程序,仅更改它创建 Company 类实例的方式(然后它将以与默认方式相同的方式填充属性):
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];
// create the Cart if there wasn't one in the session data
if (customProfile == null)
{
customProfile = new CustomProfile("default name");
controllerContext.HttpContext.Session[sessionKey] = customProfile;
}
return new Company(customProfile);
}
else
{
//just in case this gets registered for any other type
return base.CreateModel(controllerContext, bindingContext, modelType)
}
}
}
您只需将其添加到 global.asax Application_Start 方法中即可仅为 Company 类型注册此绑定程序:
ModelBinders.Binders.Add(typeOf(Company), CompanyModelBinder);
另一种选择可能是通过继承 DefaultModelBinder 使用 Ninject 依赖项创建依赖项感知模型绑定器(当您使用 Ninject 时,它知道如何构建具体类型的实例,而无需注册它们)。
但是,您需要配置一个自定义方法来在 Ninject 中构建 CustomProfile,我相信您可以使用 ToMethod() 来完成。
为此,您需要在控制器工厂之外提取 Ninject 内核的配置:
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 => /*try to get here the current session and the custom profile, or build a new instance */ );
}
}
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);
}
}
在这种情况下,您将创建此模型绑定器:
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)
}
}
您可以将 global.asax 更新为:
IKernel kernel = NinjectBootStrapper.GetKernel();
ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory(kernel));
ModelBinders.Binders.DefaultBinder = new NinjectModelBinder(kernel);