C# 模型绑定器提供者是否应被视为服务定位器?
我想为我的可查询web api提供一些自定义模型绑定,即为以下接口:C# 模型绑定器提供者是否应被视为服务定位器?,c#,asp.net,design-patterns,asp.net-web-api,model-binding,C#,Asp.net,Design Patterns,Asp.net Web Api,Model Binding,我想为我的可查询web api提供一些自定义模型绑定,即为以下接口: IQueryOptions`1 ISortingOptions`2implementingIQueryOptions`1 IPagingOptions`2实施ISortingOptions`2 根据控制器操作上指定的参数,我希望提供正确的模型绑定器 public void Test([ModelBinding] IPagingOptions<MyEntity, int> pagingOptions) //
IQueryOptions`1
implementingISortingOptions`2
IQueryOptions`1
实施IPagingOptions`2
ISortingOptions`2
public void Test([ModelBinding] IPagingOptions<MyEntity, int> pagingOptions)
// -> PagingOptionsModelBinder
我这样问是因为一方面,服务定位是一种(可怕的,IMHO)反模式,因为对于要绑定的每一种新类型,我都需要更改模型绑定器提供程序,但另一方面,如果没有在这里完成,则查找正确提供程序的责任只会委托给ASP.NET WebApi,我每次都需要注册一个新的供应商。我曾经看到过一个聪明的方法(不记得在哪里,当我找到它时,我会给它评分)是创建一个通用模型绑定器:
public class EntityModelBinder<TEntity>
: IModelBinder
where TEntity : Entity
{
private readonly IRepository<TEntity> _repository;
public EntityModelBinder(IRepository<TEntity> repository)
{
_repository = repository;
}
public object BindModel(ControllerContext controllerContext,
ModelBindingContext bindingContext)
{
ValueProviderResult value = bindingContext
.ValueProvider.GetValue(bindingContext.ModelName);
var id = Guid.Parse(value.AttemptedValue);
var entity = _repository.GetById(id);
return entity;
}
}
公共类EntityModelBinder
:IModelBinder
其中tenty:实体
{
专用只读IRepository存储库;
公共EntityModelBinder(IRepository存储库)
{
_存储库=存储库;
}
公共对象绑定模型(ControllerContext ControllerContext,
ModelBindingContext(绑定上下文)
{
ValueProviderResult值=bindingContext
.ValueProvider.GetValue(bindingContext.ModelName);
var id=Guid.Parse(value.AttemptedValue);
var entity=\u repository.GetById(id);
返回实体;
}
}
然后在提供程序中使用反射:
public class EntityModelBinderProvider
: IModelBinderProvider
{
public IModelBinder GetBinder(Type modelType)
{
if (!typeof(Entity).IsAssignableFrom(modelType))
return null;
Type modelBinderType = typeof(EntityModelBinder<>)
.MakeGenericType(modelType);
var modelBinder = ObjectFactory.GetInstance(modelBinderType);
return (IModelBinder) modelBinder;
}
}
公共类EntityModelBinder提供程序
:IModelBinderProvider
{
公共IModelBinder GetBinder(类型modelType)
{
如果(!typeof(Entity).IsAssignableFrom(modelType))
返回null;
类型modelBinderType=typeof(EntityModelBinder)
.MakeGenericType(模型类型);
var modelBinder=ObjectFactory.GetInstance(modelBinderType);
返回(IModelBinder)modelBinder;
}
}
之后,您只需注册一个永不更改的提供程序。这来自Jimmy Bogards的文章“智能模型绑定与模型绑定提供程序”@LosTechies:;)伟大的感谢吉米·博加德斯。:)这个解决方案对您不起作用吗?您有什么问题吗?为了涵盖希望使用WebAPI而不是MVC的用户:
config.Services.Insert(typeof(ModelBinderProvider),0,new MyModelBinderProvider())代码>其中MyModelBinderProvider:ModelBinderProvider
而不是MyModelBinderProvider:IModelBinderProvider
。
public class EntityModelBinder<TEntity>
: IModelBinder
where TEntity : Entity
{
private readonly IRepository<TEntity> _repository;
public EntityModelBinder(IRepository<TEntity> repository)
{
_repository = repository;
}
public object BindModel(ControllerContext controllerContext,
ModelBindingContext bindingContext)
{
ValueProviderResult value = bindingContext
.ValueProvider.GetValue(bindingContext.ModelName);
var id = Guid.Parse(value.AttemptedValue);
var entity = _repository.GetById(id);
return entity;
}
}
public class EntityModelBinderProvider
: IModelBinderProvider
{
public IModelBinder GetBinder(Type modelType)
{
if (!typeof(Entity).IsAssignableFrom(modelType))
return null;
Type modelBinderType = typeof(EntityModelBinder<>)
.MakeGenericType(modelType);
var modelBinder = ObjectFactory.GetInstance(modelBinderType);
return (IModelBinder) modelBinder;
}
}