我有2个数据API的要求,这两个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
如何实现?
答案 0 :(得分:1)
好吧,您确实回答了自己的问题。如果要确保在多个类上实现相同的方法,则这是接口的用途。您只需使每个控制器实现相同的接口,就可以了。
为确保类似的路由结构,可以为此使用继承。定义基本抽象控制器类。您可以选择在此处实现您的接口,然后以抽象方式“实现”所需的方法。任何派生类都将被迫在基类上实现任何抽象方法,因此它与接口具有相同的效果。从技术上讲,这意味着您可以根据需要放弃该接口,而只依赖于基类来强制实现。由你决定。然后,您可以将路由属性应用于抽象方法,如下所示:
[Route("[controller]/api")]
public abstract BaseApiController : ControllerBase
{
[HttpGet("action1")]
public abstract IActionResult Action1();
[HttpGet("action2")]
public abstract IActionResult Action2();
}
答案 1 :(得分:0)
如果您要处理需要类似业务逻辑的不同实体,则可以创建通用基本控制器并注入常见的依赖项:
[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);
}
}