0

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?

3
  • not clear understand, but you can take a look for Route filter, add route filter to action. learn.microsoft.com/en-us/aspnet/core/mvc/controllers/… Commented Jan 24, 2019 at 10:20
  • the route you described can only be manually set as it route is usually {domain}/{controller}/{action} per your example of what you want the route would be more something like {domain}/api/Testcontroller/action1 and {domain}/api/DemoController/action1 Commented Jan 24, 2019 at 10:28
  • i mean inheritance aside can you clarify on this part before answering the rest is this what you want or exactly per your example. Commented Jan 24, 2019 at 10:28

2 Answers 2

1

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();
}
Sign up to request clarification or add additional context in comments.

Comments

0

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);
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.