我的团队需要使用这个框架为我们的公司和产品开发一个框架。其中一个必要条件是可以为特定客户定制产品,但它应该很容易用同一产品的另一个版本进行更新(不是自动的)。
我们正在使用 ASP.NET MVC 4 + Web API(目前,明年将基于我们的框架创建桌面产品)、NHibernate、大量使用 Autofac 作为 DI 容器和 N 层的 IoC。
因此,在 WebApp 的某些方面,我们使用 ViewModels 作为具有一个默认实现的接口,并使用 Autofac 将它们链接起来,这在未来的定制中很容易改变。
在 ASP.NET MVC 中,我们实现了 IModelBinderProvider 并创建了一个继承 DefaultModelBinder 的自定义类:
像这样的东西:
public class MyCustomMVCModelBinderProvider : IModelBinderProvider
{
public IModelBinder GetBinder(Type modelType)
{
if (modelType.IsInterface)
return new MyCustomMVCModelBinder();
return new DefaultModelBinder();
}
}
public class MyCustomMVCModelBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var context = new ModelBindingContext(bindingContext);
var item = DependencyResolver.Current.GetService(bindingContext.ModelType);
Func<object> modelAccessor = () => item;
context.ModelMetadata = new ModelMetadata(new DataAnnotationsModelMetadataProvider(),
bindingContext.ModelMetadata.ContainerType, modelAccessor, item.GetType(), bindingContext.ModelName);
return base.BindModel(controllerContext, context);
}
}
在我的控制器中,我只使用接口作为参数。因此,它工作正常,因为值已正确填充。
但是,如何在正确绑定值的 Web API 中执行相同的操作?我尝试实现 IModelBinder 并继承 ModelBinderProvider。我可以获得接口实现的实例,但未填充值。
这是 WebAPI 中的一个尝试实现:
public class MyCustomWebAPIModelBinderProvider : ModelBinderProvider
{
public override IModelBinder GetBinder(System.Web.Http.HttpConfiguration configuration, Type modelType)
{
return new MyCustomWebAPIModelBinder();
}
}
public class MyCustomWebAPIModelBinder : IModelBinder
{
public bool BindModel(System.Web.Http.Controllers.HttpActionContext actionContext, ModelBindingContext bindingContext)
{
if (bindingContext.ModelType.IsInterface)
{
var item = GlobalConfiguration.Configuration.DependencyResolver.GetService(bindingContext.ModelType);
if (item != null)
{
Func<object> modelAccessor = () => item;
var a = bindingContext.ModelMetadata.ContainerType;
var b = modelAccessor;
var c = item.GetType();
var d = bindingContext.ModelName;
bindingContext.ModelMetadata = new ModelMetadata(new DataAnnotationsModelMetadataProvider(), a, b, c, d);
bindingContext.Model = item;
return true;
}
}
return false;
}
}
我错过了什么?有没有可能做我们想做的事?