Как повторно использовать методы NonAction между контроллерами - PullRequest
1 голос
/ 27 июля 2011

Допустим, у меня есть такой класс контроллеров.

public class InStorePickupController : Controller
{
    private readonly IToppingService _toppingService;
    public InStorePickupController(IToppingService toppingService)
    {
        this._toppingService = toppingService;
    }

    public ActionResult GetPizza()
    {
        var pizzaModel = new PizzaModel();
        pizzaModel = MakePizza(pizzaModel);
        return View(pizzaModel);
    }

    [NonAction]
    public PizzaModel MakePizza(PizzaModel pm)
    {
        var toppings = _toppingService.GetAllToppings();
        //roll out dough
        //put toppings on pizza
        //bake pizza
        return pm;
    }

}

Но у меня также есть другой класс контроллеров, где я хочу использовать то же действие «Make Pizza» без действия.

public class DeliveryController : Controller
        {
            private readonly IToppingService _toppingService;
            public DeliveryController(IToppingService toppingService)
            {
                this._toppingService = toppingService;
            }

            public ActionResult GetPizza()
            {
                var pizzaModel = new PizzaModel();
                pizzaModel = MakePizza(pizzaModel);
                return View(pizzaModel);
            }
    }

Это простой пример, но он очень близко соответствует моей реальной ситуации. Разница лишь в том, что:

  1. У меня есть несколько неактивных методов, и они довольно сложны (много вычислений).
  2. У меня довольно много контроллеров, которым нужен доступ к этим не действиям. Это не ползучесть контроллера, поэтому объединение их не сработает.
  3. Каждый контроллер имеет несколько необходимых служб в конструкторе.

Я мог бы каждый контроллер наследовать от базового класса контроллера, но я продолжаю получать жалобы на конструктор без параметров.

А как насчет статических классов?

Мне просто нужно небольшое руководство. Спасибо.

Ответы [ 5 ]

4 голосов
/ 27 июля 2011

Атрибут [NonAction] является запахом кода для меня. Это означает, что вы помещаете некоторый код в контроллер, но для меня не должно быть никакого другого кода в контроллере, кроме тонких действий. И попытка повторно использовать NonAction между контроллерами является подтверждением того, что вы делаете что-то не так. Вот почему у вас есть сервисные уровни, репозитории, модели ... так много мест, где можно реорганизовать этот код и поставить ваши контроллеры на диету .

2 голосов
/ 27 июля 2011

Базовый класс - это потенциальный путь, с помощью которого вы можете сделать что-то вроде:

public class PizzaControllerBase : Controller
{
  protected readonly IToppingService ToppingService;

  protected PizzaControllerBase(IToppingService toppingService)
  {
    ToppingService = toppingService;
  }

  public PizzaModel MakePizza(PizzaModel model)
  {
    // Stuff
  }
}

public DeliveryController : PizzaControllerBase
{
  public DeliveryController(IToppingService toppingService)
    : base(toppingService) { }

  public ActionResult GetPizza()
  {
    var pizzaModel = MakePizza(new PizzaModel());
    return View(pizzaModel);
  }
}

Или ввести новую услугу, IPizzaService:

public interface IPizzaService
{
  PizzaModel MakePizza(PizzaModel model);
}

public class PizzaService : IPizzaService
{
  private readonly IToppingService ToppingService;

  public PizzaService(IToppingService toppingService)
  {
    ToppingService = toppingService;
  }

  public PizzaModel CreatePizza(PizzaModel model)
  {
    // Stuff
  }
}

Который вы можете вместо этого ввести в свой контроллер.

1 голос
/ 27 июля 2011

Почему бы не создать новый IPizzaService, который обрабатывает проблемы с пиццей и вводит это?IPizzaService также может принимать зависимость IToppingService, поэтому он получает сервис топинга, который был внедрен в ваш класс контроллера.

Сервис, конечно, должен работать с объектами модели домена (не с объектами модели представления)) согласно комментариям ниже.Используйте Automapper для сопоставления между ними.

0 голосов
/ 27 июля 2011

Вы можете создать вспомогательный класс и вызвать метод, который вы хотите использовать в обоих контроллерах.

0 голосов
/ 27 июля 2011

Добавьте метод к вашему PizzaModel классу.

public class PizzaModel
{
    public static PizzaModel MakePizza(PizzaModel pm)
    {
        var toppings = _toppingService.GetAllToppings();
        //roll out dough
        //put toppings on pizza
        //bake pizza
        return pm;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...