Как обеспечить одинаковые конечные точки в двух разных контроллерах ASP.Net Core API? - PullRequest
0 голосов
/ 24 января 2019

У меня есть требование иметь 2 API данных, каждый из которых должен иметь одинаковые методы или конечные точки для реализации.Например, у нас может быть интерфейс, чтобы убедиться, что два класса будут иметь одинаковые функции.В остальном вы определяете контракт.

public interface ITest
{
    void Foo();
}

public class Test : ITest
{
    public void Foo()
    {
        // Some logic
    }
}

public class OtherTest : ITest
{
    public void Foo()
    {
        // Some other logic 
    }
}

Точно так же я хочу контроллеры, у которых будут маршруты и методы, как показано ниже.Скажем, в одном добавлено новое действие, код должен применять его в другом контроллере.

DemoController
-- GET demo/api/action1
-- GET demo/api/action2

TestController
-- GET test/api/action1
-- GET test/api/action2

Как этого добиться?

Ответы [ 2 ]

0 голосов
/ 25 января 2019

Если вы имеете дело с различными объектами, для которых требуется схожая бизнес-логика, вы можете создать универсальный базовый контроллер и также ввести свои общие зависимости:

[Route("api/[controller]")]
[ApiController]
public class GenericBaseController<T> : ControllerBase where T : class
{
    private readonly ILogger _logger;

    public GenericBaseController(ILogger<GenericBaseController<T>> logger) {
        _logger = logger;
    }

    [HttpGet("get")]
    public IActionResult Get()
    {
        //...
    }

    [HttpPost("post")]
    public IActionResult Post(T value)
    {
        //...
    }
}

, затем вы можете расширить универсальный контроллер:

[Route("api/[controller]")]
[ApiController]
public class MyFirstController : MyFirstController<FirstModel>
{
    public GenericBaseController(ILogger<MyFirstController> logger) : base(logger) 
    {
    }
}

еще один:

[Route("api/[controller]")]
[ApiController]
public class MySecondController : GenericBaseController<SecondModel>
{
    public MySecondController(ILogger<MySecondController> logger) : base(logger) 
    {
    }
}

Вам не нужно заново создавать методы для каждого унаследованного контроллера, если это та же логика, или вы можете расширить любой из них, если вам нужно:

[Route("api/[controller]")]
[ApiController]
public class MyThirdController : GenericBaseController<ThirdModel>
{
    public MyThirdController(ILogger<MyThirdController> logger) : base(logger) 
    {
    }

    [HttpPost("post")]
    public IActionResult Post(ThirdModel value)
    {
        // do some logic...
        return base.Post(value);
    }
}
0 голосов
/ 24 января 2019

Ну, вы вроде как ответили на свой вопрос, правда.Если вы хотите убедиться, что одни и те же методы реализованы в нескольких классах, то для этого нужны интерфейсы.Вы просто заставляете каждый контроллер реализовывать один и тот же интерфейс, и все готово.

Что касается обеспечения аналогичной структуры маршрутизации, вы можете использовать для этого наследование.Определите базовый абстрактный класс контроллера.Вы можете либо реализовать свой интерфейс здесь, и «реализовать» требуемые методы как абстрактные.Любой производный класс будет вынужден реализовывать любые абстрактные методы в базовом классе, поэтому он имеет тот же эффект, что и интерфейс.Технически это означает, что вы можете отказаться от интерфейса, если хотите, и просто положиться на базовый класс, форсирующий реализацию.Вам решать.Затем вы можете применить атрибуты маршрута к вашим абстрактным методам следующим образом:

[Route("[controller]/api")]
public abstract BaseApiController : ControllerBase
{
    [HttpGet("action1")]
    public abstract IActionResult Action1();

    [HttpGet("action2")]
    public abstract IActionResult Action2();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...