1

可以在我的控制器中为我的模型绑定器调用一个静态字段吗?Unity IoC和MVC模型绑定

例如,

public class AuctionItemsController : Controller 
{ 
    private IRepository<IAuctionItem> GenericAuctionItemRepository; 
    private IAuctionItemRepository AuctionItemRepository; 

    public AuctionItemsController(IRepository<IAuctionItem> genericAuctionItemRepository, IAuctionItemRepository auctionItemRepository) { 
     GenericAuctionItemRepository = genericAuctionItemRepository; 
     AuctionItemRepository = auctionItemRepository; 
     StaticGenericAuctionItemRepository = genericAuctionItemRepository; 
    } 

    internal static IRepository<IAuctionItem> StaticGenericAuctionItemRepository; 

这里是我使用Unity作为国际奥委会ModelBinder的

public class AuctionItemModelBinder : DefaultModelBinder 
{ 
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { 
     if (AuctionItemsController.StaticGenericAuctionItemRepository != null) { 
      AuctionLogger.LogException(new Exception("controller is null")); 
     } 

     NameValueCollection form = controllerContext.HttpContext.Request.Form; 

     var item = AuctionItemsController.StaticGenericAuctionItemRepository.GetSingle(Convert.ToInt32(controllerContext.RouteData.Values["id"])); 

     item.Description = form["title"]; 
     item.Price = int.Parse(form["price"]); 
     item.Title = form["title"]; 
     item.CreatedDate = DateTime.Now; 
     item.AuctionId = 1; 


     //TODO: Stop hardcoding this 
     item.UserId = 1; 

     return item; 
    }} 

,我觉得很奇怪在IoC容器注册我的ModelBinder的。

我推荐的其他优秀设计考虑因素是什么?

回答

3

不,我不会考虑这个好做法。一般而言,API设计的美妙之处在于,只要某些事物看起来很奇怪,就会引发精神警觉。关键字static对我有影响。

一旦开始使用静态属性,就没有理由从Controlller获取存储库 - 您可能也可以直接从容器中获取它,这将暗示Service Locator anti-pattern。就像现在一样,您将ModelBinder紧密耦合到一个特定的控制器,尽管似乎没有任何理由要这样做。从技术上讲,你可以做你已经做的事情,但是要考虑它是否是正确的地方:现在你已经从存储库获得了你的物品,为什么不立即再次保存它呢?这在技术上也是可能的,但这是对Single Responsibility Principle的严重违反。

想想ModelBinder的预期责任:它将HTTP/HTML上下文信息(以纯文本形式给出)转换为强类型对象。而已。如果你试图让它做更多,你打破了SRP。

基于HTML Form/querystring值的脱水最好留给控制器本身。一旦控制器具有适当的域对象,它就可以将其交给域模型。这应该是财务主任的单一责任。在大多数情况下,您根本不需要ModelBinder。