Location, Location, Location: Where to place code

Where do you place a shareable, UI extension method? Today, I share my discussion I had with a fellow developer and look for feedback from others

Written by Jonathan "JD" Danylko • Last Updated: • Develop •

Hand pointing on a map

In today's post, I wanted this to be more of a discussion for my fellow developers as to where certain code should reside.

This is a true story of a developer discussion over the past week.

In this recent discussion, I was asked to help out with an ASP.NET MVC application. They wanted a quick and easy way to create a dropdown list based on an IEnumerable<T>.

This was an easy approach since I wrote a couple posts about creating an extension method for generating SelectListItems.

Open-and-shut case, right?

Not quite.

There's always a piece of code that stands out from the rest of the application as a utility function/method/helper. Should it be shared? Should it be added to the infrastructure folder?

The discussion was similar to a familiar fairy tale of "not too hot," "not too cold," or "no, not there." It ended up being "just right" for the developer.

Scope: Local (controller)

At first, we decided to place this into the controller. Use the service to pull the list of items and then create the IEnumerable<SelectListItem> for the ViewModel.

Done!

Right?

Not entirely.

"Not a good place," said the developer, "I want to be able to create other dropdowns for other ViewModels without copying the code." (Remember the DRY principle).

Ok, next thought.

Scope: Local (Extensions Folder)

Taking it to the next level, why not create an extension folder in the root of the UI application and place extension methods dealing with UI into the folder (Everyone knows how I LOVE extension methods).

"But I would like the code usable in other ViewModels."

"With this approach, it would be usable across all ViewModels in the application," I said.

"What if other people want to use it? Is it possible to move this into a library?"

I said, "sure, you can place it into a class library."

Scope: Class Library

We started looking at the existing shared libraries in their solution and picked a nice location for the code. 

As I started adding the extension method to the library, I thought about this.

Their class library didn't have any UI code (which I thought was a good thing).

This extension method would drag the Microsoft.AspNet.Mvc assembly into the class library because of the SelectListItem generated by the extension method.

Would this make sense to reference a UI library in a shared class library?

I said, "I'm thinking we don't want to include UI code in a class library. Let's focus on creating it in the UI application."

Scope: Inheritance through ViewModel

Maneuvering back into the UI, we decided to go with the BaseViewModel approach which I described in ASP.NET MVC ViewModel: Make Your ViewModels More Functional.

I always thought this made sense.

Any time you want to create a dropdownlist using SelectListItems, you'll always have a list in your ViewModel. So why not have some code to help create your SelectListItems. This gives you a more efficient way of creating dropdownlists for every one of your views.

And it's centralized in the BaseViewModel.

Conclusion (and analysis)

After going back and forth as to where the code should reside, we agreed on building it into a BaseViewModel as a method. It can always be refactored later.

This was an interesting topic and it's funny how quickly it escalated from being local in a controller to "Can others use this in a class library?"

Ron Burgundy saying 'Boy that escalated quickly.'

While this story was more of "where does the code essentially reside," it shows the code may need refactored to a new location based on whether they want it available for all ViewModels in the application or placed in a shared library for others to use. 

Here was my take on this.

  • I still think creating a folder called Extensions with extension methods (such as ToSelectList()) would be ideal since we are dealing exclusively with UI components and the System.Web.Mvc assembly is already included.
  • If, in the future, they want to place it into a shared library for other applications to use, they may have to bite the bullet and include the System.Web.Mvc assembly into the shared library. This is what happens when you bundle a class library up with NuGet, right? So it's not entirely unheard of.
  • Is an inheritance approach to ViewModels so bad? In my CMS, I have a BaseViewModel with the following properties for SEO optimization: Title, Abstract, and Keywords so I don't need to create the properties every single time.

I'm sure a number of developers have experienced this at one time or another. It's always good to discuss this with other developers so we can all grow.

In the long run, this leads developers down the road of best practices and possibly architectural discussions.

But tell me what you think? Did I make the right call?

What are your thoughts on this approach? Did you think this was the right place to put the code? Post your comments below and let's discuss.

ASP.NET 8 Best Practices on Amazon

ASP.NET 8 Best Practices by Jonathan Danylko


Reviewed as a "comprehensive guide" and a "roadmap to excellence" with over 120 Best Practices for ASP.NET Core 8, Jonathan's first book by Packt Publishing explores proven techniques for every phase of the SDLC.

Learn industry-standard concepts to improve your coding, debugging, and deployment of ASP.NET Core websites.

Order now on Amazon.com button

Picture of Jonathan "JD" Danylko

Jonathan "JD" Danylko is an author, web architect, and entrepreneur who's been programming for over 30 years. He's developed websites for small, medium, and Fortune 500 companies since 1996.

He currently works at Insight Enterprises as an Architect.

When asked what he likes to do in his spare time, he replies, "I like to write and I like to code. I also like to write about code."

comments powered by Disqus