CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

My Thoughts on ASP.NET's MVC

Like me, you might have been surprised that the foundation series didn't have a chapter on the MVC pattern. I'm no fan of the existing page model (I actually think it's horrible), and I've successfully used MonoRail on a few projects, so it would have made for a good topic. My reasons for not including something on MVC were simple: we were and continue to be flooded with MVC information (as though it's a brand new invention), and I didn't think I could explain MVC using MonoRail effectively (I find it has a steep learning curve). I considered using RoR, but figured that would confuse people even more.

Hopefully though, if you're a fan of the foundation series, you've already downloaded the learning application which puts the theory to practice using ASP.NET's MVC framework. So, what do I think about ASP.NET MVC? Overall I've been very impressed. I can't think of a good reason for starting a new project using the WebForms model - or MonoRail for that matter (sorry). If you're an ASP.NET developer, it's really a no brainer.

I do have two major issues with it though. First, if you come from almost any other MVC framework (MonoRail, Django, RoR, Akelos, etc...) you might be expecting an actually Model framework - instead you get an empty Model folder. In other words, the MVC framework doesn't add anything to the .NET O/R Mapping / DAL story. From Microsoft's point of view this makes sense, since they feel that they are already offering solid solutions - DataSets, SqlDataSources, LINQ to SQL, Entity Framework. Truth be told, this is fine with me, as it lets me use NHibernate. I just think, given what the other MVC frameworks offer, it's a little dishonest - you'll end up disappointed if you're expecting to be able to do this out of the box:

public class Car : ActiveRecord
{
}
....
Car.FindById(1);

My real problem though is simply that neither C# nor VB.NET lend themselves all that well to view logic. Jeff Atwood actually just blogged the same criticism. Jeff uses RoR to highlight the problem. I don't fully agree. I won't say that RHTML is great, but I will say that it's far better than C# or VB.NET. I think views need a specialize language - I'm sure that anyone who's done some significant work in either RoR or Django would agree. There are solutions available now - NVelocity and Boo (I assume you could use it with the MVC framework?), but I'm just going to trudge along with C# until IronRuby is a viable solution.

Aside from that, everything is pretty solid - routes work great, helper methods are adequate (they're starting to add more and more), and testing is actually doable - I haven't run into any problems, but from what I've read things aren't 100% perfect yet (either way, it's a huge step up from WebForms).

So, to recap. MVC good. WebForms Bad. C# in views less than ideal. Empty Model folder = M. Oh, and download the learning application!.

T4 Templates for Code Generation Screencast

T4 Template ScreencastI put together a quick screencast showing how to leverage T4 Templates in Visual Studio 2008 for Code Generation:

I show step-by-step how to create a simple T4 Template and then how to generate various Entity, Data Access Object, and Factory Classes using more advanced T4 Templates that one might use to create a simple custom data access layer. I have seen other screencasts that have used SQL Server Management Objects, but in my case I use database schema related functionality in good 'ol ADO.NET. Although I wouldn't use this technique to build a data access layer given all the cool code generators and O/R Mappers, it is a pretty decent way to show the possibilities with T4 Templates.

I picked up a new iPhone 3G the other day and absolutely love it, so I also created a version of the screencast that you can download and play on the iPhone. In fact, several of the more recent Unity and Enterprise Library 4.0 Screencasts now have an iPhone version.

If you are interested in some of the ADO.NET techniques I used in the screencast to get database schema information, check out the show notes with links to various tutorials.

I hope the screencast is useful.

Dealing with Code Un-Coverable by Tests

Code UnCoverable by Tests

Even for test-coverage addict (as me), there is some code that simply cannot be covered by tests. An example?

The call to MessageBox.Show() cannot be tested automatically since it is blocking. Of course we could mock calls to MessageBox.Show(), but at the end of the day, there will be at least one call to this method in the code base, one call that cannot be covered by tests.

This example is not isolated. There are a multitude of cases where code reacts to things that cannot be automatized, such as exception that cannot be reproduced…

…but also some environment settings, folder or file browsing by user, showing a modal custom dialog and more.

 

The Problem

As we explained above, while using mocking can help reduce the surface of code not-coverable by tests, it can’t help to get a code base 100% covered. When exploring test coverage results, with NCoverExplorer, Visual Studio Team System or NDepend, this problem will lead to classes 98% or so covered. It is taking time and it is error prone to figured out each time you are exploring coverage results, that these are false alert. This is clearly anti-agile! What we want is a clean 100% coverage result!

 

The Solution

NCover and NDepend are tackling this problem the same way: you can exclude some methods from coverage results through a dedicated (and eventually custom) attribute.

NCover knows about this attribute through the /ea command line option as describe here by Jamie Cansdale. Code tagged with this attribute will be excluded from coverage statistics and won’t disturb while exploring test coverage results. For example, if all methods of the class Foo are 100% covered except the method MessageBoxShow(), if the method MessageBoxShow() is tagged with the coverage exclude attribute then the class Foo will be shown as 100% covered. A great side-effect is that developers reviewing the code will know about this coverage exclusion.

With NDepend, the coverage excluding attribute can be provided through the import coverage file dialog as shown below. This will have the same effect as with NCover. For convenience, the assembly NDepend.CQL.dll can be linked from your project. This assembly contains the dedicated attribute: NDepend.CQL.UncoverableByTestAttribute. If you prefer you can provide your own attribute.


 

As far as I know, Visual Studio team System Coverage doesn’t support yet this feature but it might be considered for future releases, as explained here.

 

The Bonus

Actually the burden of exploring coverage results to make sure that some classes or namespaces should be 100% covered is not really agile. It is manual, time consuming, error-prone and cannot be capitalized for future iterations.

NDepend can help automate this task with just 2 CQL rules:

// <Name>Types 100% covered by tests</Name>
WARN IF Count > 0 IN SELECT TYPES WHERE 
HasAttribute "NDepend.CQL.FullCoveredAttribute" AND PercentageCoverage < 100
 
// <Name>Methods 100% covered by tests</Name>
WARN IF Count > 0 IN SELECT METHODS WHERE 
HasAttribute "NDepend.CQL.FullCoveredAttribute" AND PercentageCoverage < 100

 

Basically, these rules will check automatically that all types and methods tagged with the attribute FullCoveredAttribute are indeed 100% covered. Insert these rules in your build process and you’ll be informed as soon as a lack of test coverage is luring. Here also, as a bonus side-effect developer reviewing or refactoring the code will know instantly which part of the code is supposed to be 100% covered.  For applying this trick to the code base of NDepend since the code coverage feature is available, I can testify that it is a really, really time saving trick.

For convenience, the assembly NDepend.CQL.dll can be linked from your project and it contains the dedicated attribute: NDepend.CQL.FullCoveredAttribute (and also the attribute NDepend.CQL.MoreThan95PercentCoveredAttribute). Of course, CQL rules can be readily tweaked to work with a custom attribute.

 

Ward & I talk over the EF Vote of No Confidence Document

The second part of Ward Bell & I's conversation on ORM is up at the ALT.NET Podcast.  In this part we dive right into the vote of no confidence document that kicked up so (much more than was justified) fuss and racket about a month ago.

We recorded it a couple weeks back, and I've spent a little time thinking about the EF VoNC. At this point I'd say that:

  1. After looking more at it, EF v1 is actually worse than I thought it was

  2. No, I don't regret signing and helping to write the no confidence thing.  I wish it had unfolded differently and I'm disappointed at the negativity around it, but I still think it was worth doing.  I still don't think the wording of the document was very inflammatory, but I guess the idea of openly criticizing a Microsoft product is still taboo for big areas of the .Net community.  If nothing else, it's actually sparked something of a real dialog between two or more camps of development that rarely communicate with each other

  3. What I've heard from EF v2 (Mr. Bellware goes to Redmond, Washington) sounds pretty good.  The EF team might have already been on the cleaner POCO path anyway.  I really wish they'd been a bit more transparent and upfront about that.  From all appearances, it's always looked like the EF team was completely blowing off our original concerns about the usability of EF.  Anyway, here's to hoping the EF team's new openness and transparency leads to a better relationship from now on. 

  4. I think EF v2 sounds like it might be usable from my perspective, so would I recommend using EF v1 if you want all that EDM stuff and migrate to the POCO model in v2 later?  I'm going to make the sure to be controversial standpoint that it'll be easier to start with NHibernate now and migrate to EF v2 later than it would be to start with EF v1.

  5. Regardless of what they do, I think the EF is unlikely to completely succeed.  The EF is getting yanked into way too many directions to make everybody happy.  Look at their fancy advisory council.  Some DDD guys, an Agile guru, a database weenie who wants to write all his code in T-SQL sprocs like it's 1995, and an MDA guy.  How could one single tool make all of those different people happy without collapsing under its own complexity?  Oh, and tou think ALT.NET whines about the EF?  On a couple different occasions I've watched data centric guys yell at the EF team for perceived shortcomings in stored procedure support.  I couldn't tell you the specifics of their complaints though, because I snoozed off as soon as I heard the words "stored procedure."

  6. ALT.NET gets a rap for bad behavior, but in the wake of the VoNC document, I thought the traditionalists (the TechEd/INETA/Regional Director types) behaved poorly as well.  The kicker for me was Stephen Forte's crack that developers want ORM's because they're too stupid and lazy to learn set-based algebra, then says that he hopes "cooler heads" will prevail later in the exact same post.  Um, rank hypocrisy anyone?

Bellware Driven Design

When I was down in Seattle last week Scott Bellware did a talk about BDD for a few people. Its not a very formal talk (which I prefer) and its a bit slow to start but there are some gems in here. My camera died after the first hour but definitely worth checking out.

 

Enjoy!

 

Ward's Wiki is still a great resource

I have no idea if it's still being updated, but I'm floored by how useful and relevant Ward's Wiki is today 10+ years after its inception.  I'm doing research for an article today and the single most helpful source of information and thought is *still* the original Wiki.  If you're a student of software design, and object oriented design in particular, do yourself a favor and spend some time perusing the conversations that happened there way back when (late 90's ish).


Creating a PIDX Partner Interface Process (PIP) in BTARN 3.5

The next step in developing your PIDX / RNIF solution using the BizTalk Accelerator for RosettaNet (BTARN 3.5) is to create a new Process Configuration from your PIDX PIP. I’m going to use the PIDX “Invoice” and “Invoice Response” PIPs (P21 & P22) in this example since they are generally the most important in the Energy, Oil & Gas industry right now.

1. You begin by opening the BTARN Management Console and right-clicking on the Process Configuration Settings node in the left-hand pane and selecting New > Process Configuration.

2. For PIDX configurations I recommend using a Display Code that includes the standard, the PIP and the version like “PIDX_P21_1.0”. This will make things a lot easier if you need to support multiple versions in the future. The Process Code corresponds to the PIP number which is “P21” in our case. The Version is “1.0” and the Process Name is “Invoice”. The Message Standard is “PIDX”, the Standard Version is “1.0” and the Payload Binding ID is also “PIDX. Once you are done, your General tab should look like this.

3. The parameters you set on the Activity tab are very important and the required values can be found in the PIDX Implementation Guide. To meet the PIDX requirements, the Non-Repudiation Required, Is Authorization Required and Non-Repudiation of Origin and Content parameters must all be set to “True” and the Type parameter must be set to “Request/Response”. The settings for all other parameters on the Activity tab must be agreed upon by both parties involved in the transaction. Once you are done, the Activity tab should look like this.

4. The parameters you set on the Initiator tab are also very important and these are all specified by the PIDX P21 Invoice PIP documentation. It’s very important that you communicate these settings to your trading partner as well since they must be the same on both messaging systems. Once you are complete the Initiator tab should look exactly like this.

 

5. The same goes for the Responder tab as shown here.

There are a lot of parameters to set when creating a new Process Configuration in the BizTalk Accelerator for RosettaNet. Almost all of these are used by the Initiator Private Process and Initiator Public Process to create the outbound RNIF headers and message so it’s vital that you and your trading partner agree on all these before you begin testing.

It’s pretty sad how complicated this is compared to an alternative such as AS2. As I’ve said before using RosettaNet is like “swatting a fly with an atom bomb”.

Currently listening to Eric Marienthal’s Just Around the Corner.

More Posts Next page »



What's New

CodeBetter.Com Blogs

Karl Seguin
126 Posts | 1,129 Comments | 323 Trackbacks
Patrick Smacchia [MVP C#]
60 Posts | 231 Comments | 282 Trackbacks
David Hayden [MVP C#]
282 Posts | 761 Comments | 577 Trackbacks
Jeremy D. Miller -- The Shade Tree Developer
550 Posts | 4,068 Comments | 1,840 Trackbacks
Greg Young [MVP]
93 Posts | 543 Comments | 248 Trackbacks
Jeff Lynch [MVP]
228 Posts | 491 Comments | 103 Trackbacks
Dave Laribee
58 Posts | 420 Comments | 136 Trackbacks
Matthew Podwysocki
35 Posts | 99 Comments | 101 Trackbacks
Glenn Block
44 Posts | 148 Comments | 87 Trackbacks
Kyle Baley - The Coding Hillbilly
87 Posts | 469 Comments | 150 Trackbacks
Steve Hebert's Development Blog
310 Posts | 540 Comments | 96 Trackbacks
Ian Cooper [MVP]
33 Posts | 184 Comments | 134 Trackbacks
James Kovacs
34 Posts | 117 Comments | 38 Trackbacks
Peter's Gekko
536 Posts | 2,324 Comments | 580 Trackbacks
Aaron Jensen
10 Posts | 34 Comments | 18 Trackbacks
Rod Paddock
37 Posts | 145 Comments | 40 Trackbacks
Jacob Lewallen
5 Posts | 40 Comments | 7 Trackbacks
Raymond Lewallen
298 Posts | 1,946 Comments | 346 Trackbacks

Other Blogs

CodeBetter.Com Events
3 Posts | 0 Comments | 13 Trackbacks
CodeBetter.Com Link Blog
178 Posts | 9 Comments | 2 Trackbacks
All About Products
2 Posts | 5 Comments | 2 Trackbacks
Featured Articles
1 Posts | 4 Comments | 1 Trackbacks

CodeBetter.Com Alumni

Jay Kimble -- The Dev Theologian
424 Posts | 1,431 Comments | 167 Trackbacks
Jean-Paul S. Boodhoo
136 Posts | 475 Comments | 139 Trackbacks
Don Demsak
5 Posts | 14 Comments | 1 Trackbacks
Eric Wise
290 Posts | 1,486 Comments | 215 Trackbacks
Brian Peek [MVP C#]
15 Posts | 15 Comments | 3 Trackbacks
Mark DiGiovanni
88 Posts | 322 Comments | 42 Trackbacks
Paul Laudeman
113 Posts | 231 Comments | 23 Trackbacks
Ben Reichelt's Weblog
172 Posts | 514 Comments | 70 Trackbacks
Ranjan Sakalley
41 Posts | 272 Comments | 6 Trackbacks
Public Class GeoffAppleby
300 Posts | 1,943 Comments | 108 Trackbacks
DonXML - Live From PDC
3 Posts | 4 Comments | 3 Trackbacks
Grant Killian's Blog
171 Posts | 473 Comments | 8 Trackbacks

CodeBetter.Com Emeritus

Darrell Norton's Blog [MVP]
727 Posts | 2,382 Comments | 331 Trackbacks
Jeffrey Palermo (.com)
654 Posts | 2,478 Comments | 620 Trackbacks
Brendan Tompkins [MVP]
405 Posts | 2,721 Comments | 347 Trackbacks