1

Можно ли установить в моем контроллере статическое поле для моего модельного звонка?Unity IoC и MVC modelbinding

Например.

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; 

вот 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; 
    }} 

я использую Unity в качестве IoC, и я нахожу это странным, чтобы зарегистрировать свою ModelBinder в контейнере IoC.

Любые другие хорошие конструктивные соображения, которые я делал?

ответ

3

Нет, я бы не подумал об этой хорошей практике. Красота дизайна API в целом и DI в частности заключается в том, что, как только что-то начинает выглядеть странно, оно должно вызывать психическое предупреждение. Ключевое слово static оказывает на меня такое влияние.

Как только вы начнете использовать статические свойства, нет никаких оснований для получения вашего репозитория из Controlller - вы можете просто получить его непосредственно из контейнера, и это будет означать Service Locator anti-pattern. Как и сейчас, вы плотно соединяете ваш ModelBinder с конкретным контроллером, хотя, похоже, нет причин, по которым вы хотели бы это сделать.

Технически вы можете делать то, что вы уже делаете, но подумайте, правильно ли это место: теперь, когда у вас есть ваш предмет из хранилища, почему бы не сохранить его снова сразу? Это также технически возможно, но большое нарушение Single Responsibility Principle.

Подумайте о предполагаемой ответственности ModelBinder: это перевести контекстную информацию HTTP/HTML (заданную простым текстом) в строго типизированный объект. Вот и все. Если вы попытаетесь сделать это больше, вы нарушите SRP.

Дегидратация, основанная на значениях формы HTML/Querystring, лучше оставить самому контроллеру. После того, как контроллер имеет собственный объект домена, он может передать его в модель домена. Это должна быть единственная ответственность Контролера. В большинстве случаев вам совсем не нужен ModelBinder.

Смежные вопросы