Reputation: 150
I have a requirement to have 2 data api's both of which should have same methods or endpoints to be implemented. For example, we can have an interface to make sure, two classes will have same functions. Otherworldly, you define the contract.
public interface ITest
{
void Foo();
}
public class Test : ITest
{
public void Foo()
{
// Some logic
}
}
public class OtherTest : ITest
{
public void Foo()
{
// Some other logic
}
}
Similarly, I want controllers which will have routes and methods like below. Say in one a new action is added, the code should enforce it in the other controller.
DemoController
-- GET demo/api/action1
-- GET demo/api/action2
TestController
-- GET test/api/action1
-- GET test/api/action2
How to achieve this?
Upvotes: 0
Views: 1368
Reputation: 5719
if you are dealing with different entities that requires similar business logic, you can create generic base controller and inject your common dependencies as well:
[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)
{
//...
}
}
then you can extend the generic controller :
[Route("api/[controller]")]
[ApiController]
public class MyFirstController : MyFirstController<FirstModel>
{
public GenericBaseController(ILogger<MyFirstController> logger) : base(logger)
{
}
}
another one:
[Route("api/[controller]")]
[ApiController]
public class MySecondController : GenericBaseController<SecondModel>
{
public MySecondController(ILogger<MySecondController> logger) : base(logger)
{
}
}
You don't have to re-create the methods for each inherited controller if it is the same logic, or you may extend any of it if you need:
[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);
}
}
Upvotes: 0
Reputation: 239300
Well, you've sort of answered your own question, really. If you want to ensure that the same methods are implemented on multiple classes, that is what interfaces are for. You just make each controller implement the same interface and you're good to go.
As for ensuring a similar routing structure, you can use inheritance for that. Define a base abstract controller class. You can either choose to implement your interface here, and "implement" the required methods as abstract. Any derived class will be forced to implement any abstract methods on the base class, so it has the same effect as an interface. That technically means you can forgo the interface, if you want, and just rely on the base class forcing the implementation. Up to you. Then you can apply route attributes to your abstract methods like so:
[Route("[controller]/api")]
public abstract BaseApiController : ControllerBase
{
[HttpGet("action1")]
public abstract IActionResult Action1();
[HttpGet("action2")]
public abstract IActionResult Action2();
}
Upvotes: 1