0

I'm trying to develop an ASP.NET MVC-application with an additional Web API. To reduce code-duplication, I'd like to share as much code as possible, but with the possibility to differentiate between the two projects if needed.

My plan is to create a Shared Class Library that contains:

  • Entity-classes
  • Service-classes
  • ViewModel-classes

For example:

 class Post { public int Id { get; set; } public string Body { get; set; } public Author Author { get; set; } } class Author { public int Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } } class PostViewModel { public int PostId { get; set; } public string PostBody { get; set; } public string AuthorName { get; set; } } class BlogService { public IEnumerable<PostViewModel> GetPosts() { //retrieve entity's from DB and convert to ViewModel-objects return new List<PostViewModel>(); } } 

But with this approach, I'm affraid of the tight-coupling between the ViewModels in the MVC-application and the Web API.

A solution could be to let the Service return a DTO-object and to let the controller handle the conversion to the right ViewModel (API Controller -> API-specific, Web Controller -> Web-specific), but this seems like a lot of boilerplate-code to handle the conversions between the different layers.

Do you have any best practices regarding this scenario?

Thank you in advance!

4
  • I think my biggest question is, why does the MVC application need to use the same classes as the web API? Why isn't the MVC application delegating to the API for those operations?CommentedNov 2, 2022 at 13:14
  • @GregBurghardt: isn't that overkill, since I can call the services/classes directly in my controller?
    – Sam
    CommentedNov 2, 2022 at 13:18
  • If you aren't calling the web API from the MVC app, why does the web API even exist? You are introducing coupling between applications if the MVC app is directly using classes from the web API.CommentedNov 2, 2022 at 14:12
  • @GregBurghardt: Some websites offer an API endpoint that mirrors what you can do on the site itself. You'd only reuse the Web API if the website was a client-side SPA (or similar), as opposed to a server-side rendered MVC application. Furthermore, you'd likely want to be able to scale your MVC app and your Web API differently, which is why you'd split them into two separate projects.
    – Flater
    CommentedJan 12, 2024 at 3:39

2 Answers 2

1

ViewModels are there to service the views, so they more correctly belong in the MVC project.

There are many ways to skin a cat, but I'd be inclined to have the domain models in their own project with both the MVC & Web API projects referencing it.

You could also have an interfaces project to simplify dependency injection to be able to test each of the layers in isolation.

    0

    For this answer, I want to zoom in on your observation:

    but this seems like a lot of boilerplate-code to handle the conversions between the different layers

    That's not an argument for why it shouldn't be done, it's an argument for why it should be done as painlessly as possible.

    The short answer

    A mapping tool like Automapper can significantly help cut down on boilerplate fluff. You still have to map it, but it's significantly less copy/pasting between different endpoint to make sure the mapping gets executed.

    The longer answer

    One of the main reasons people put clean coding practices aside is "because it's too much boilerplate". That observation, however, is made by someone who is used to performing non-clean coding practices, and therefore the effort needed to clean up the code looks like it's extra work.

    As someone who is very used to clean coding by now, I could call those non-clean coding practices bad "because it cuts too many corners". Same argument, but from a different side.

    Notice the different observations here. The key difference is that the person in the first paragraph and me (in the second paragraph) are disagreeing on what is the "normal" amount of code that is expected.

    So when you say that it's "too much boilerplate", you have to acknowledge that this is based on your own opinion on how much code should be written. This is the part where I ask you to re-evaluate your own bias - how convinced are you that your idea is the objectively and universally correct one? How can you be sure that you're not mistakenly thinking that the "normal" amount of code you expect is actually less than it should be? (This is rhetorical, discussing this is an endless back and forth)

    While clean coding does force you to do some of the work upfront when you're setting things up, it pays back dividends that are multiple times the effort you invested in the long run. If it didn't, no company or experienced developer would be advocating for clean coding (nor would they call it that).

    Going back to your scenario, while it's going to take additional effort to set up this additional layer, it will start saving you time once you start making changes to the shared logic. You will avoid "updated one, forgot another" kinds of bugs and regressions because there now only is one thing to update that affects both use cases.

    It may not seem like much today, because today is where you have to put in the effort to make it so. However, clean coding is cumulative. Today, you will put in extra effort and avoid future trouble. Tomorrow, you will also put in extra effort in a different part of the codebase, and you will avoid future trouble.

    Do this enough days in a row, and your daily developer experience will be significantly easier and lighter than if you had avoided the good practice.
    The reason this may not seem apparent to you now, in the assumption that you've never really worked in a clean coding environment, is because you don't realize that the kinds of bugs and issues you have in the future, or more specifically their difficulty, was caused by some bad practice decisions you made in the distant past.

    The bugs will still happen. Clean coding does not stop you from making mistakes, or from the requirements changing.

    But the bugs/changes will be significantly easier to identify, locate, and fix/implement. I can attest from personal experience that between the best and worst projects I've worked on, I could either fix 6-10 bugs in a day with no stress (best) or 1 bug would take me a week of complicated tracking and getting to grips with difficult to read code, and the fix would be very liable to cause another issue somewhere else in the codebase.

      Start asking to get answers

      Find the answer to your question by asking.

      Ask question

      Explore related questions

      See similar questions with these tags.