How to keep your Get & Post ViewModels DRY
I’ve been convinced that I should not be using the same view model class for both loading the view and the posted controller action parameter. The trouble is it allows data to be transferred back which may not be necessary and it needlessly increases our attack surface. Don’t get me wrong, I’ve always had unit tests specifically monitoring that only necessary view model properties are being pushed back to the entity model, but still, seperate viewmodels will allow me to eliminate that risk completely and even remove those tests. To be honest, the idea of having 2 view model classes that are nearly identical is not very appealing, especially given that if the structure deviates, the default model binder will no longer work with those properties which are out of sync with its partner view model. Don’t get me wrong, I’m very liberal when it comes to class quantities, but this was enough to make me uncomfortable. So I’m happy that I realized the post view model class can always be used as a base class for the get view model class. I mean it has to be in order for the default model binder to work. Using inheritance for these classes will a) keep these classes in sync so the default model binder will always work, b) follow the DRY principle and c) keep my sanity. In a nutshell, rather than having 1 2 3 4 5 6 7 public class FooViewModel { public int Id { get; set; } public string Name { get; set; } public FooStatusEnum Status { get; set; } public DateTime CreateDate { get; set; } }public class FooViewModel { public int Id { get; set; } public string Name { get; set; } public FooStatusEnum Status { get; set; } public DateTime CreateDate { get; set; } } We can instead have 1 2 3 4 5 6 7 8 9 10 11 public class FooPostViewModel { public int Id { get; set; } public string Name { get; set; } } public class FooGetViewModel : FooPostViewModel { public FooStatusEnum Status { get; set; } public DateTime CreateDate { get; set; } }public class FooPostViewModel { public int Id { get; set; } public string Name { get; set; } } public class FooGetViewModel : FooPostViewModel { public FooStatusEnum Status { get; set; } public DateTime CreateDate { get; set; } } So FooGetViewModel is loaded and passed into the view.... read moreA simple proposal to rule out obvious software patents
I just read the EFF’s new website (https://defendinnovation.org/) about how to change the patent system to prevent the patent trolls from stifling innovation. I like some of the ideas, but question how realistic others are (i.e. #3? – C’mon; How many implementations in how many languages will you need to write to cover all your bases?) I realize this is an extremely naive statement to make, but I’m going to make it anyway; solving the ‘non-obvious’ aspect of a software patent is simple. … and it doesn’t involve judges learning to code. Here’s my proposal: Software patent proposals should include a unit test suite and a single solution implementation. The test suite would be made public immediately, without the implemented solution. The public would take a crack at making the test suite pass. If there are no successful passes, then it could be deemed as a difficult problem with a non-obvious solution. If the patent office is bombarded with working solutions, then it unquestionably fails the ‘non-obvious’ test. It’s debatable what to do if a relative few brilliant developers solve it, while most fail. But this would definitely eliminate laughable patents like Amazon’s 1-Click which would have bombarded the patent office in less than an... read moreMy take on identifier semantics (Id vs No vs Code vs Key)
My simple conventions for these popular identifier names. I don’t believe they’re all the same, and should be used under different circumstances.
read moreDiscovering Typemock
Frustration mocking static methods, the ridiculous hoops I was forced to jump through, and the clean implementation I was finally able to do with Typemock.
read moreThe UI programmers (not so) secret weapon
An Example: Suppose you had software which matches buyers and sellers, and new users are created via a ‘new user’ wizard[1]. Let’s say the wizard has 4 pages for Basic User Info, Review, Processing, and Completion Status Report. And there are 5 buttons; Cancel, Previous, Next, Run, and Finish. Cancel is displayed from the Basic User Info, Review, and Processing pages. Previous is displayed from the Review page. Next is displayed from the Basic User Info page. Run is displayed from the Review page. Finish is displayed from the Completion Status Report page. This isn’t difficult to manage the display from the events[2] right? Well … in reality, it doesn’t take much of a change for your simple display functionality to become … The Problem Manipulating application display during events quickly turns into a complex, bug riddled, difficult to maintain, mess. It may not seem like that big of a deal when you have only a few controls and a very simple (or no) workflow. Actually, you may argue, managing visual display in the events may even seem like the most efficient strategy. After all, you will never display, disable, or otherwise needlessly manipulate a control, but as your application grows more complex, this approach can leave you tearing your hair out[3]. This is especially true when you have multiple execution paths leading to the same event handlers with different state. What if you received a change request for the above requirements, where additional info is required for buyers or sellers, resulting in a new wizard page for each, and in addition to that, business sellers require a page to gather Tax Information? Your complexity has started to grow, resulting in buyers have a workflow of Basic User Info -> Buyer Info -> Review -> Processing -> Completion Status Report Individual sellers have a workflow of Basic User Info -> Individual Seller Info -> Review -> Processing -> Completion Status Report And commercial sellers have a workflow of Basic User Info -> Commercial Seller Info -> Tax Info -> Review -> Processing -> Completion Status Report Notice how these changes lead to different execution paths all arriving at the Review page. The question then, is; where does the back button on the Review page send the user? The back button requires logic to know which wizard page to display. It’s not difficult to imagine the need for logic to be added in more than one place[4], which can result... read moreWhat is too simple and small to refactor? (Clean Code Experience No. 2)
Shortly after reading Clean Code, I refactored the data access layer from a project I was working on, and was amazed by how much the code improved. It really was night and day. My first clean code refactoring experience was an obvious improvement.
I was still on that clean code high, when a little function entered my life that I was compelled to refactor. This one left me questioning the limits of what I should refactor and if my refactor even qualified as clean.
I’d like to share that second experience with you in this post.
read more