Unity IoC和MVC模型绑定

时间:2010-05-18 17:36:08

标签: model-view-controller dependency-injection unity-container

我的控制器中有一个静态字段可供我的模型绑定器调用吗?

EG。

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;

这是模型绑定器

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;
    }}

我使用Unity作为IoC,我觉得在IoC容器中注册我的模型绑定器很奇怪。

我要做的其他任何好的设计考虑事项吗?

1 个答案:

答案 0 :(得分:3)

不,我不会考虑这个好习惯。一般来说API设计之美,特别是DI,就是一旦看起来很怪异,它就会引发精神警报。 static关键字对我有影响。

一旦开始使用静态属性,没有理由从Controlller获取存储库 - 您也可以直接从容器中获取它,这意味着Service Locator anti-pattern。就像现在一样,你将你的ModelBinder紧密耦合到一个特定的控制器,尽管似乎没有理由你想这样做。

从技术上讲,你可以做你已经做过的事情,但要考虑它是否是正确的地方:既然你有来自存储库的项目,为什么不立即再保存呢?这在技术上也是可行的,但却违反了Single Responsibility Principle

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

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