Category Archives: Code

Posts containing code

Dirty Code Monday!

Lately I’ve been thinking about how easy it is to fall into the trap of not challenging our ideas about the code we’re working on. In order to challenge the default mindset of Clean Code, I recently proposed to institute Dirty Code Monday (a proposal that sort of got me into a bit of a big discussion).

Anyway, here is the report from the first successful Dirty Code Monday one week ago:

An unpromising start: I had done a code review with “Programmer A”‘s code on Thursday where “Programmer H” and I had pretty much rewritten all of it. Now we had to go through the results together. We all admitted that code review is not ideal for a Dirty Code Monday, but rules are rules.

The first bit of code we came across was this:

Notice the comment? // TODO: Find out if SSLContext.getSocketFactory is expensive an if so, cache. I sighed. “We really have to remember not to do premature optimization, or we’ll never find out if it is really slow or not.” “Programmer A” responded “What? I thought you said this was Dirty Code Monday! Let’s just do it!” And so we did. We cached the result of createSocketFactory in a static variable. Dirty Code Monday!

By now, I was starting to get my spirits up that we could actually pull this off. We glanced up at the on-wall monitor: Someone had broken the build. “Sorry,” said ‘Programmer K’, “I forgot that my commit also changed the backend.” ‘Programmer R’ chimed in: “Yay! Your turn to get cake, K”. “Not today,” said A, “Dirty Code Monday!”

‘Project manager K’ just mumbles “The cake is a lie”.

I continued the code review with A. Next up was this beauty:

“Hmm…” I said, “I guess that really should deal with DELETE and PUT requests, too. But it’s Dirty Code Monday.” We discussed a little and A mused “a switch-case could work here”. “Ugh! I say, I don’t like switch-statements. They kinda violate the OCP. Maybe. Maybe not here. But I still don’t like it.” He just looked at me and we both laughed.

“Ooooh,” I said. “Look at that repetition of the complicated stream() expression. Perfect!” ‘Programmer A’ was pleased as well “Dirty Code Monday is pretty okay.”

Perhaps you think our code wasn’t that dirty. I’m actually not that embarrassed about it. But changing our perspective helped us see other ways of working with the code than we were used to. Having a phrase like “Dirty Code Monday” was a fun thing for the team to talk about. I’d like to try it again today.

Happy Dirty Code Monday, everybody!

PS: The code in this article is actual production code. The whole team has approved the quotes attributed to them

Posted in Code, English, Java, Pair programming | Leave a comment

How to write better code

My previous blog post took off on Twitter. It pointed out a problem: Insisting on the obligation to follow certain rules at all times isn’t actually helping people work better. The most common question (or objection) I got to the blog post was: So how do we teach new coders how to code well. This blog post is about that topic.

First learn to collaborate

The most important skill we should teach is how to work well with others on a shared code base. In my career, it took me many years before I started getting good at this, but it had the most impact on my effectiveness. So this is where I want to start with developers who are getting ready to join the work force. On almost all projects we work on, our success will depend on others.

Working with others can be taught. Here are some techniques that have worked for me:

  • Pair programming. Good pair programming requires training, but there exists training styles like coding dojos and code retreats. Some of the best programming instructors in the world use pair programming actively as part of their training.
  • Code reviews. I work so much with pair programming that I personally give code reviews a lower priority. But many teams find great value in them.
  • Patience. When working with pair programming, it’s easy to get stuck in arguments. Our profession says almost nothing about interpersonal skills, yet we depend on them all the time. Try this: When pair programming and you see your pair making a mistake, wait to see if she spots it herself before breaking in.
  • Humility. I often get asked “how do I convince others to write clean code”. Of course, the question assumes that you’re right and they are wrong. Most of us are absolutely rubbish at the skill of changing our minds. When pair programming, if your pair want do something you think is wrong, try indulging them. At worst, you get the chance to teach them something. At best, you learn something yourself.

Unless you are in a situation where you write all the code yourself, collaboration skills are paramount. It doesn’t matter if you “know” what the code should look like if you can’t agree with your team.

Now, let’s talk about code!

If you are one of the people who skipped ahead to this section, please go back and read about collaboration. Seriously. Nothing I say about code will help you if you can’t work well with others.

Go ahead, read it again. I’ll wait here.

Good to see you back! Now let’s talk about learning to write good code. Of course good code is crucial to professional success. If the code base is better, you spend less time fixing bugs, you have an easier time changing the code in the future and your team will have a better time working with you. This is understood.

Learning to write good code is quite simple: You have to read code, you have to write code, you have to change code, you have to observe what is easy and what’s hard, and you have to delete code and start over again.

For the first of these points, great books help you to read code: Clean Code, Implementation Patterns, Refactoring, the Art of Agile, the Pragmatic Programmer, Practices of an Agile Developer, Design Patterns. I’ve enjoyed reading all these books immensely. These books will teach you considerations such as low coupling, high cohesion and simple design. They will teach you useful principles like Single Responsibility Principle and the Open-Closed Principle (although I find I almost never refer to the rest of SOLID). The patterns and principles teaches you words to discuss code with your team.

For the second of these points, Test-Driven Development is one great way to learn how to write code. I enjoy doing coding katas myself and often use them for teaching. But the most valuable skill when writing code is one I learned at code retreats (thank you, Corey Haines!). Learn to delete code you write. I don’t just mean refactor it to be smaller. I mean that for coding exercises, highlight all the files and press the delete button. I mean for production code, after spending a few hours working on a task, (occasionally) git reset --hard HEAD.

The hallmark of great code is how easy it is to change. Can you navigate in the code? Can you spot errors quickly? Do you know where to make a specific change? You can learn by reading about principles, but the most safe teacher is to expose yourself to more experience. (I’m planning to write a blog post on how principles sometimes, but not always coincide with good code). When you write and change code, reflect on how limitations of the code and your current skillset impedes the changes you want to make.

In short: Code more, listen to the code and listen to your peers.

Can you release smoothly

I almost forgot the #1 quality of good code: It has to be used! Release cycles of teams can vary from several times per day until a few times per year. If you can release your code at will, you can learn both about your code and your users. When the whole team learns that you will release again tomorrow, or next week, priorities of “now or later” gets easy. When you release only a few times a year, people get stressed and discussions get heated.

I’ve almost always find that team under-appreciate the value of spending time on build and deployment tools and scripts.

“Don’t do stupid stuff on purpose”

If you find code you’re unhappy with, it bears remembering that it is that way because it got that way. People did what they did because of reasons. Those reasons are valid, whether it was because the surrounding needs changed, because the developer had insufficient experience, because of pressure to finish, because they wanted to go home to their family instead of sitting late in the office or maybe they just had a difference in opinion on what’s good code.

Not everyone agrees with this, “what about those who just don’t care?” After 20 years of working as a programmer, I have never encountered anyone who just didn’t care. I have encountered programmers who had different preferences from my own, I’ve encountered programmers who are delivering under short deadlines, I’ve encountered programmers who get praised for making appearant progress at the expense of writing good code. And I’ve encountered many programmers who don’t care as much as me about the code. Having other interests in our life is an excellent reason to spend less time polishing code.

But I’ve never encountered a programmer who just doesn’t care. Have you? I’d love to learn from your story.

Posted in Code, English, Pair programming | Leave a comment

A wicked Java trick to make the JVM forget to check exceptions

I’ve long time been a critic of the mechanism of compiler checked exceptions in Java. Whether you love them or hate then, one thing is sure: There’s situations where you don’t want to have to deal with them. The solution in Java is to wrap a checked exception in new RuntimeException(e) but this gives long stack traces without adding useful information. Sometimes, we just want to tell the compiler to chill.

As it turns out this is possible, through some wicked abuse of the type erasure misfeature of Java-generics. Seeing this in action is instructive for understanding the inner workings for Java. Let’s go!

Here is what we want:

Notice that the businessLogic() neither catches IOException or declares that it throws IOException. Instead, the softenException() method removes the checkedness of the exception. When we run it, we get the following stack trace:

Huh! The exception being thrown in the main method is a NoSuchFileException, which is a subclass of IOException – a checked exception! How can that be? Why didn’t any of the methods in the program have to declare throws IOException?

Here’s the trick:

The checkednessRemover method uses a trick that reveals a few things about the inner workings of Java. First, the generic type argument T is bound to RuntimeException in order to fulfill the contract of softenException. This means that the expression throws T becomes throws RuntimeException, which the compiler interprets as if there was no exceptions thrown.

But the statement throw (T)e; theoretically should evaluate to throw (RuntimeException)e;. Since e is a NoSuchFileException, you would expect this statement to result in a ClassCastException. But the way generics work in Java, the type information is removed by the compiler. So instead, the bytecode reads as throw (Exception)e;, which is fine.

So this strange trick shows that the Java compiler removes generic information from the compiled code and that checked exceptions is purely a feature of the compiler. There are no runtime verifications of checked exceptions.

Would I recommend using this trick in production code? I don’t know. It’s pretty weird and may not be that useful, but I do use it myself when I’m feeling wicked. If nothing else, I hope learning about has given you some insights into the inner workings of Java.

Disclaimers: (1) I read about this trick somewhere else, but I cannot find the source any longer. I thought it was Heinz Kabutz’ excellent Java Specialist newsletter, but I can’t find the source. (2) This is also implemented in Project Lombok as @SneakyThrows. If you are using Lombok, you should under no circumstance reimplement the trick from this blog. Use @SneakyThrows instead.

Posted in Code, English, Java | 3 Comments

Interactive REST hacking with Sublime Text and RESTer

Do you ever miss a command line to a web application? If you’re lucky, you may use a REST API with appropriate tools for the same job.

This Christmas, I bought a Sonos system for our family. It’s a wireless speaker system that uses music streaming services. It supports both Spotify and Deezer, but works better with Deezer and it came with a one year free subscription, so Deezer it is.

First order of business: Importing Spotify playlists into Deezer. I found a free service that does this, but by accidentally refreshing the browser a couple of times, I managed to import five copies of each playlist. Disaster!

Thus began my quest: I had a number of accidentally imported playlists in Deezer, and it turns out that after deleting a playlist, I needed about five clicks, including hitting a small icon, in order to delete the next. This was not going to be fun.

As a programmer, you know there must be a better way. Perhaps that better way requires more time because you have to program something, but dammit, better is better. In the case of Deezer, I found that they had a well-documented REST API. But this time, I didn’t feel like writing a program just to solve this one problem. And so we get to the core of this post: How can you just execute a fairly large number of API calls without writing a program for it? All I needed to do was to find out which set of API calls needed to be made based on my playlist listing and execute these.

My text editor of choice these days is Sublime Text, which has a number of plugins. The RESTer plugin was just what I needed.

So, in order to delete the extra playlists:

  1. I installed SublimeText 3, Package Manager and RESTer
  2. Looking at the Deezer API doc, I created a test application and entered the URL: https://connect.deezer.com/oauth/auth.php?app_id=YOUR_APP_ID&redirect_uri=http://localhost& perms=basic_access,email,delete_library&response_type=token in a web browser. This gave me an authorization dialog with Deezer that ends up redirecting to an invalid URL on localhost. However, the URL will be something like http://localhost/#access_token=xxxxxxxxxxxxxxxxxx&expires=3600. Just copy the access_token part, as this will be needed for later.
  3. Now, let’s list the playlists. In Sublime Text, I write the URL http://api.deezer.com/user/2529/playlists?access_token=xxxxx (replace the id with your own user id and the access_token with the result from last step) and press ctrl-alt-r. This executes the REST call and returns the result in a new buffer as a formatted JSON text.
  4. In Sublime Text, I bring up the search dialog with ctrl-f, click the “.*” button (regular expression), enter "title"|"picture" and press “Find All”. This selects all the relevant lines from the JSON response.
  5. Now, some Sublime Text editing magic. All the lines from the output are selected. Press shift-end to extend the selections to the end of their lines, ctrl-c to copy the texts to the clipboard, ctrl-a to select everything, del to delete and ctrl-v to paste it.
  6. Whoa! That should replace the text with a set of alternating lines like "title": "something" and "picture": "something". We almost have what we want. Double click on the word "title" on any line and press alt-f3. This selects all the places where it says "title" in the buffer. Press end to move to the end of the lines and del to join the line with the next.
  7. Now each playlist should be on a separate line with the title and the picture link. Press F9 to sort the lines. In my example, I can now clearly see all the lines the are duplicates. So I delete the lines I want to keep and keep the lines I want to delete. For all playlists with duplicates, I remove one line in my buffer and keep the rest for deleting.
  8. Now I just have to craft the delete commands. I double click an example of the word picture. I press right-arrow until the cursors (several!) are between the ” and the https-part. Press shift-home to select everything before https://api... and del press to delete this. Press end to go to the end of the line and backspace until you have deleted the ‘/image”,’ part so each URL looks like “https://https://api.deezer.com/playlist/number“.
  9. We now have our targets to delete. At this point in time, I went to the beginning of the buffer and pressed ctrl-alt-down arrow until I have a cursor at the start of all lines. I now type “DELETE “, press end, paste in the access_token from step 2 and press enter. I now have all the requests that I need to execute separated by a blank line!
  10. Finally, I go to the first line, press ctrl-alt-r which executes the HTTP request. I press ctrl-w to close the response, go down two lines and press ctrl-alt-r to do it again.

This is the result of the first request:

This is what my buffer looks like after selecting titles and pictures and joining the lines:

This is what my buffer looked like in the end.

Sometimes, doing an everyday Christmas task like deleting a lot of playlists is hard to do with the programs available. Luckily, with a little bit of programming knowledge and some sharp tools, you can get the job done through an API.

Posted in Code, English | Leave a comment

Promises you can trust

JavaScript Promises provide a strong programming model for the future of JavaScript development.

So here I’m playing with promises.

First I need a bit of a package.json file:

Now I can write my first test (test/promises_test.js):

Notice that the “it” function takes a “done” function parameter to ensure that the test waits until the promise has been resolved. Remove the call to done() or to resolve() and the test will timeout.

This test fails, but because of a timeout. The reason is that done is never called. Let’s improve the test.

Using “done()” instead of “then()” indicates that the promise chain is complete. If we haven’t dealt with errors, done will throw an exception. The test no longer times out, but fails well:

And we can fix it:

Lesson: Always end a promise chain with done().

In order to separate this, you can split the then and the done:

There is another shorthand for this in Mocha as well:

But what is a promise chain?

This is extra cool when we need multiple promises:

Notice that done is only called when ALL of the strings have had their length calculated (asynchronously).

This may seem weird at first, but is extremely helpful when dealing with object graphs:

Here, the save methods on dao.orderDao and orderLineDao both return promises. Our “savePurchaseOrder” function also returns a promise which is resolved when everything is saved. And everything happens asynchronously.

Okay, back to basics about promises.

Here, the second function to “done()” is called. We can use “fail()” as a shortcut:

But this is not so good. If the comparison fail, this test will time out! This is better:

Of course, we need unexpected events to be handled as well:

And of course: Something may fail in the middle of a chain:

The failure is automatically propagated to the first failure handler:

It took me a while to become really comfortable with Promises, but when I did, it simplified my JavaScript code quite a bit.

You can find the whole source code here. Also, be sure to check out Scott Sauyet’s slides on Functional JavaScript for more on promises, curry and other tasty functional stuff.

Thanks to my ex-colleague and fellow Exilee Sanath for the inspiration to write this article.

Posted in Code, English, Java | 1 Comment

Dead simple configuration

Whole frameworks have been written with the purpose of handling the configuration of your application. I prefer a simpler way.

If by configuration we mean “everything that is likely to vary between deploys“, it follows that we should try and keep configuration simple. In Java, the simplest option is the humble properties file. The downside of a properties file is that you have to restart your application when you want it to pick up changes. Or do you?

Here’s a simple method I’ve used on several projects:

The AppConfiguration class looks like this:

This reads the configuration file in an efficient way and updates the settings as needed. It supports environment variables and system properties as defaults. And it even gives a pretty good log of what’s going on.

For the full source code and a magic DataSource which updates automatically, see this gist: https://gist.github.com/jhannes/b8b143e0e5b287d73038

Enjoy!

Posted in Code, English, Java | Leave a comment

The lepidopterist’s curse: Playing with java.time

Pop quiz: What will be the output of this little program?

The answer is, like with most interesting questions, “it depends”. How can it depend? Well, let try a few examples:

  • getHoursOfDay(LocalDate.of(2014, 7, 15), ZoneId.of("Asia/Colombo")) returns 24. As expected
  • getHoursOfDay(LocalDate.of(2014, 7, 15), ZoneId.of("Europe/Oslo")) also returns 24.
  • But here comes a funny version: getHoursOfDay(LocalDate.of(2014, 3, 30), ZoneId.of("Europe/Oslo")) returns 23! This is daylight saving time.
  • Similarly: getHoursOfDay(LocalDate.of(2014, 10, 26), ZoneId.of("Europe/Oslo")) also returns 25
  • And of course, down under, everything is upside down: getHoursOfDay(LocalDate.of(2014, 10, 5), ZoneId.of("Australia/Melbourne")) gives 23.
  • Except, of course, in Queensland: getHoursOfDay(LocalDate.of(2014, 10, 5), ZoneId.of("Australia/Queensland")) => 24.

Daylight saving hours: The bane of programmers!

Daylight saving hours were instituted with the stated purpose of improving worker productivity by providing more working hours with light. Numerous studies have failed to prove that it works as intended.

Instead, when I examined the history of daylight saving hours in Norway, it turns out that it was lobbied by a golfer and a butterfly collector (“lepidopterist”) so that they could better pursue their hobbies after working hours. Thus the name of this blog post.

Most of the time, you can ignore daylight saving hours. But when you can’t, it can really bite you in the behind. For example: What does the hour by hour production of a power plan look like on the day that changes from daylight saving hours to standard time? Another example given to me by a colleague: TV schedules. It turns out that some TV channels just can’t be bothered to show programming during the extra hour in the fall. Or they will show the same hour of programming twice.

The Joda-Time API and now, the Java 8 time API java.time can help. If you use it correctly. Here is the code to display a table of values per hour:

Given 2014/10/26 and Oslo, this prints:

And on 2014/3/30, it prints:

So, if you ever find yourself writing code like this: for (int hour=0; hour<24; hour++) doSomething(midnight.plusHours(hour)); you may want to reconsider! This code will (probably) break twice a year.

At the face of it, time is an easy concept. When you start looking into the details, there's a reason that the java.time library contains 20 classes (if you don't count the subpackages). When used correctly, time calculations are simple. When used incorrectly, time calculations look simple, but contain subtle bugs.

Next time, perhaps I should ruminate on the finer points of Week Numbers.

Posted in Code, English, Java | Leave a comment

C# tricks: Securing your controllers

This article is dedicated to the ExileOffice team – revolutionizing the way we run our business in Exilesoft.

As applications move more and more of their business logic to the client side, it falls upon us to simplify what’s left on the server to avoid distractions. My previous article shows how I get rid of lot of the boring and noisy code.

There is one thing that the server will always be responsible for: Security. Much functionality can be moved to the client side, but we have no way of stopping users from hacking our client-side code or faking requests.

In this article, I extend upon the generic controllers to handle the one of the most important aspects of security: Authorization.

This is not your data!

The first order of business is to ensure that only logged in users can access our controller. This is trivially done with AuthorizationAttribute:

Here, our custom AuthorizationAttribute sets a property by looking for the Company of the currently logged in user in the database. You probably want to cache this in a session.

The second problem is to ensure that the user can only read and write data.

According to my previous article, we want to move as much as possible of the boilerplate logic into a generic EntityController. Here we add authorization:

Here, we give the controllers a virtual AccessFilter property. Whenever we read data, we need to run it through the access filter, and whenever we write data, we need to check that the data matches the filter.

It’s up to each entity controller to determine how to match the data. Here is an example for PersonData:

The clue here is to ensure that PersonController can only get at Persons through the Entities collection. This collection is always filtered with the Company that the user has access to.

The code will resolve to simply: db.Persons.Where(p => p.Company == Request.Properties["UserCompany"]).Where(p => p.Type == PersonType.Admin && p.City == city).Select(p => new { p.FirstName, p.LastName }). By using the filtered Entities, we can ensure that we never accidentally forget to apply the users company.

Posted in C#, Code, English | Leave a comment

A canonical web test in NodeJS

Working with web applications in NodeJS is great. Using the same language and libraries on the client and server simplified the thinking. And NodeJS has fast tests and restart for a super quick edit-verify cycle when you’re coding.

I like to write tests to verify the server-side and client-side logic, but do you know that the whole solution really is working? You can of course test your service manually after deploying, but that becomes tedious. By using Selenium, we can test that the solution works end-to-end.

In this article, I show how to write a Mocha test that:

  1. Starts up the Selenium test runner
  2. Creates a browser client that can access the application (using PhantomJS)
  3. Starts up the server and sends the browser to the server (running in ExpressJS)
  4. Clicks a button in the web page that triggers some JavaScript (written in jQuery in this example)
  5. Verifies that the call to the server returns and displays correct data

This test can be run with a simple command after you check out the code and requires no setup on the developers computer!

This test starts a new server and client for each test. When using this for real, you really want to make sure you only start the server and the web driver once as these are expensive operations.

The test case of “it clicks menu item” has a lot of callbacks. There are versions of webdriver APIs for NodeJS which are based on promises that you may enjoy using more.

Implementation details

The full application can be found on Github. To implement it, I used the following NPM modules:

  • phantomjs
  • selenium-standalone
  • webdriverjs
  • expressjs (of course)
  • mocha and chai (of course)

Starting the server looks like this:

And the app.js file looks like this:

I have a server.js file which starts up the express application to run normal (outside the tests).

A simplified version of starting Selenium and WebDriver looks like this:

I found that Selenium and PhantomJS has some issues, at least on Windows, so my final code needed a few hacks to work. See the full details at github.

Conclusion

A web end to end integration test in NodeJS requires a little bit of shaking your fist at the heavens to get to work the first time, not in the least due to the need to work around limitations in Selenium and PhantomJS. But once you got it up and running, you can easily test not only that your logic works, but that your whole application works together.

When making these tests, I allowed for a little flexibility as well: By setting environment variables, the same tests can be run with a manually deployed server, so you can use it to verify that your staging server is up and running (for example). And of course, you can replace PhantomJS as a web browser with Firefox or Chrome and see the tests run for real in your browser.

Automate the end-to-end tests of your NodeJS applications!

Posted in Code, English, JavaScript, Software Development | Leave a comment

C# Tricks: Slimming down your controllers

This blog post is dedicated to my colleague Seminda who has been experimenting with how to create simple and powerful web applications. Thank you for showing me your ideas and discussing improvements with me, Seminda.

I find many C# applications have much unnecessary code. This is especially true as the weight of the business logic of many applications are shifting from the backend to JavaScript code in the web pages. When the job of your application is to provide data to a front-end, it’s important to keep it slim.

In this article, I set out to simplify a standard MVC 4 API controller by generalizing the functionality, centralizing exception handling and adding extension methods to the DB set that is used to fetch my data.

If you generate an API controller based on an existing Entity and remove some of the noise, your code may look like this:

This code is a simplified version of what the API 4 Controller wizard will give you. It includes a GetPerson method that returns a person by Id, PostPerson which saves a new person, GetPeople which returns all people in the database, GetAdminsInCity, which filters people on city and type and DeletePerson which finds the person with the specified Id and deletes it.

I have replaced DbContext and IDbSet with interfaces instead of the concrete subclass of DbContext makes it easy to create tests that use a double for the database, for example MockDbSet.

Generify the controller

This is easy and safe as long as things are simple. As a general tip, rename you methods to “Get”, “Post” and “Index” rather than “GetPerson”, “PostPerson” and “GetPeople”. This will make it possible to generalize the controller thus:

The generic EntityController can be used for any class that is managed with EntityFramework.

Exception handling

I will dare to make a bold generalization: Most of the bugs that remain in production software are in error handling. Therefore I have a very simple guideline: No catch blocks that don’t rethrow another exception.

The actual handling of exceptions should be centralized. This both makes the code easier to read and it ensures that exceptions are handled consistently. In MVC 4, the place to do this is with a ExceptionFilterAttribute.

We can thus simplify the EntityController:

The HandleApplicationException looks like this:

This code code of course add special handling of other types of exceptions, logging etc.

DbSet as a repository

But one piece remains in PersonController: The rather complex use of LINQ to do a specialized query. This is where many developers would introduce a Repository with a specialized “FindAdminsByCity” and perhaps even a separate service layer with a method for “FindSummaryOfAdminsByCity”.

If you start down that path, many teams will choose to introduce the same layers (service and repository) even when these layers do nothing and create a lot of bulk in their applications. From my personal experience, this is worth fighting against! Needless layers is the cause of a huge amount of needless code in modern applications.

Instead, you can make use of C# extension methods:

The resulting controller method becomes nice and encapsulated:

The extension methods can easily be reused and can be freely combined.

Conclusions

With these tricks, most of your controllers would look something like this:

That’s pretty minimal and straightforward!

I’ve showed three tricks to reduce the complexity in your controllers: First, parts of your controllers can be generalized, especially if you avoid the name of the entity in action method names; second, exception handling can be centralized, removing noise from the main application flow and enforcing consistency; finally, using extension methods on IQueryable<Person> gives my DbSet domain specific methods without having to implement extra layers in the architecture.

I’d love to hear if you’re using these approach or if you’ve tried something like it but found it lacking.

Posted in C#, Code, English, Software Development | 4 Comments