Thursday, 29 October 2009 21:31 by
Hadi
The Dependency Inversion Principle states:
- A. High-level modules should not depend on low-level modules. Both should depend on abstractions.
- B. Abstractions should not depend upon details. Details should depend upon abstractions.
(Source WikiPedia).
Throw that at a terrible programmer, and all you’ll get is a terrible programmer that is annoyed and hates you. So true!
Take the following method:
public void PrintHelloMessage()
{
Console.WriteLine("Hello");
}
Now ask a developer to add a new method to print the message ‘Goodbye’. Do you think he would do:
public void PrintGoodbyeMessage()
{
Console.WriteLine("Goodbye");
}
or:
public void PrintMessage(
string message)
{
Console.WriteLine(message);
}
Most likely, he’d do the latter. Why? Because he realizes he’s gaining a benefit by passing a parameter to a method. He knows that if tomorrow you ask him for a “Good Afternoon” message, he won’t have to write a new method.
What is Dependency Injection? It’s one way of complying with the Dependency Inversion Principle. However, when you think about it, what does it boil down to? Passing a parameter to a method, which happens to be a constructor. It seems simple enough doesn’t it? Yet, it’s hard for people to understand it. Why? because they don’t see the value in it.
Explaining a principle to someone without them understanding the benefits and values they get out of it is useless, and that is why concepts such as Dependency Injection or Inversion of Control seem overly complex to the vast majority of developers (believe it or not, those of us that use these things are still a very big minority). It’s complex because they haven’t been explained the values of it. They’ve just been thrown some definition and they are expected to understand that it’s bad for one class to create an instance of another class it uses.
Present a developer with the following code:
public class AuthServices
{
public void AuthUser(string username, string password)
{
var authDAL = new AuthDAL();
var user = authDAL.GetUserByUsername(username);
if (user != null)
{
if ...
}
}
}
and ask them how they’d go about testing this code without having access to a database. Ask them how they’d go about changing AuthDAL for some fake DAL that doesn’t really connect to a database.
They’ll probably come up with the solution of passing the AuthDAL class in as a parameter, and eventually realizing that multiple methods will use the same class, they’ll pass it in via the constructor and set it as an instance field. As long as their AuthDAL has virtual methods, they can create any fake DAL that overrides those methods and returns some dummy value. They might argue that they don’t want virtual methods. And that’s fine. Tell them to define the parameter as an interface. In fact, they probably have already heard of a principle that says that you should program to an interface and not a class. They’ll eventually end up with this code:
public class AuthServices
{
IAuthDAL authDAL;
public AuthServices(IAuthDAL authDAL)
{
_authDAL = authDAL;
}
public void AuthUser(string username, string password)
{
var user = _authDAL.GetUserByUsername(username);
if (user != null)
{
if ...
}
}
}
And voila! You have Dependency Injection via Constructor.
Once they *get* that, then explain to them other benefits, you know the real benefits they get from doing this: decoupled code, easy maintenance, promotion of SRP, etc. and then throw the principle in their face:
- A. High-level modules should not depend on low-level modules. Both should depend on abstractions.
- B. Abstractions should not depend upon details. Details should depend upon abstractions.
And they’ll see how it all makes sense.
It’s not about throwing or not throwing books. It’s about showing people how something can help them, how they get value of it.
Wednesday, 14 October 2009 09:29 by
hadi
Last week I was invited to join devlcio.us, part of codebetter.com blog network. Unfortunately with all the travelling I’ve not had a chance to even do my first blog post or thank both Jak and Brendan for the invitation, and seeing I’m currently stuck at Franfurt Airport on a 5 hour layover, it’s a better time than any.
I’ll still be blogging on my regular sites, and as always, any non-technical off-topic posts will remain exclusively on my own site.
Saturday, 10 October 2009 10:01 by
hadi
Nuff said!
Really liking Resharper 5.
Friday, 9 October 2009 23:17 by
hadi
Resharper 5 has a couple of new features for MVC that can make your life somewhat easier. Take a look at the following screenshot:
That’s inside an ASPX ViewPage. The first thing is the “Abouta” underlined in blue. The hint tells me that this action does not exist. “Home” on the other hand, which corresponds to a controller is underlined, meaning you can navigate to it from there (ctrl+left mouse click).
In the case of the action not existing, if we haven’t spelt it wrong, we can ask Resharper to create it for us:
which generates the corresponding action in the controller:
Simple, yet very productive!
Friday, 9 October 2009 11:23 by
hadi
I’m having a discussion on the ASP.NET MVC forums with one of the guys from the ASP.NET team in regard to the Data Annotations in MVC 2 and I’m not sure I agree with him. Here’s an issue Jak and I have run into:
In MVC 2 there’s a new Html Helper named EditorForModel(); that renders out a form based on the properties of your model, along with the validation messages, labels, etc. So something like this:
<% using (Html.BeginForm()) {%>
<%=Html.EditorForModel() %>
<p>
<input type="submit" value="Save" />
</p>
<% } %>
you’d get something like this:
If you want to do individual fields and thus have finer control, you can use the EditorFor helper, passing in a property name. In other words, the previous could be also rendered as:
<% using (Html.BeginForm()) {%>
<%=Html.EditorFor( model => model.FirstName) %>
<%=Html.EditorFor( model => model.LastName) %>
<%=Html.EditorFor( model => model.Email) %>
<p>
<input type="submit" value="Save" />
</p>
<% } %>
but this time you don’t get the labels:
The problem however is that you lose something else: the Validation messages. If you have client-side validation enabled, the previous ASPX file generates a pretty much useless call to the EnableClientValidation JS function:
EnableClientValidation({"Fields":[],"FormId":"form0"}, null);
as opposed to:
EnableClientValidation({"Fields":[{"FieldName":"FirstName","ValidationRules":[{"ErrorMessage":"First name is required","ValidationParameters":....
// rest omitted for brevity
The result of course is that client-validation doesn’t work (and from what I’ve heard causes JS errors in some browsers).
The solution to this is to explicitly add a Validation Message, like so:
<%=Html.ValidationMessage("FirstName")%>
Now I understand that EditorFor is for fine-tuning and there is a corresponding LabelFor (although a ValidationFor doesn’t exist yet), but my main concern here is that it’s breaking the principle of least surprise from an API perspective.
For me, the only difference between EditorFor and EditorForModel should be that in the first I specify a property name explicitly whereas in the latter it just assumes the whole model. Nothing is telling me by the name of the method that the second does a whole bunch more of magic.
One solution is for EditorFor to be renamed to something else if it’s ONLY going to provide the input box (be it a text area, checkbox, radio group, etc..).
Thoughts?
Friday, 9 October 2009 10:09 by
hadi
ASP.NET MVC 2 allows you to do data validation, either using the de-facto Data Annotations or plugging in your own, much in the same way xVal work. If you’re interested in seeing how that works, take a look at this post.
This post however concerns testing. Here’s some code:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(Customer customer)
{
if (ModelState.IsValid)
{
return RedirectToAction("Index");
}
return View(customer);
}
This code checks to see if my model is valid. If it is, it then saves it (not in the code) and redirects to the index action, thus producing a RedirectToActionResult. If it is not valid, it will return a ViewResult. Here’s the model:
public class Customer
{
[Required]
public string FirstName { get; set; }
[Required]
public string LastName { get; set; }
}
Given the previous, what would you expect the following test to do? Pass or fail?
[Fact]
public void wont_give_you_any_hints()
{
var controller = new CustomerController();
var customer = new Customer();
customer.FirstName = "Jak a.k.a. Casey";
customer.LastName = String.Empty;
var result = controller.Create(customer);
Assert.IsType(typeof(ViewResult), result);
}
I’ll give you a hint. It fails. Now I understand why it fails. My problem however is that for me to test my model is valid is going to force me to change the way I have to write my code, and potentially make it less readable.
Wednesday, 7 October 2009 20:31 by
Hadi
[Note: This post applies to ASP.NET MVC 2, Preview 2.0]
Today while doing the demo for the previous post, I ran into an issue where the Javascript code for the client-side validation (the call to EnableClientValidation ) was not being output during the form rendering.
Take a look at the following two snippets:
First:
<% Html.BeginForm();%>
<%=Html.EditorForModel() %>
<p>
<input type="submit" value="Save" />
</p>
<% Html.EndForm(); %>
Second:
<% using (Html.BeginForm()) {%>
<%=Html.EditorForModel() %>
<p>
<input type="submit" value="Save" />
</p>
<% } %>
See the difference? The latter is using the using statement. In my previous post I’m using this option and all works well. However, if you go with the first option, the Javascript call will not be output. The reason for this (after debugging the source) is that the call to make this happen takes place in the Dispose method of the MvcForm. Explicitly calling Html.EndForm won’t cause this to take place.
I’ve talked to Mathew from the QA team, and he’s confirmed it’s a known issue. I think the output of the JS code should ideally be decoupled from the form construction. For instance, If I were to use a manual form tag, this wouldn’t work either [I’ve haven’t given it that much thought either].
In the meantime, if you want client-side validation, make sure you use the second option.
Wednesday, 7 October 2009 07:31 by
Hadi
ASP.NET MVC 2 Preview 2 now ships with client-side validation built into the box. It follows the same idea as the xVal framework whereby you can define validation rules once and have them enforced both on the server and the client.
By default, MVC uses Data Annotations which is available in System.ComponentModel.DataAnnotations on the server and the jQuery Validator plugin on the client. Much like xVal you can customize these to use whatever you want. I’m preparing some demos for next week of how to do client-side validation and since there isn’t much info on it, I’ve decided to post it.
Server-Side Validation
Server-side validation with Data Annotations works without having to take any additional steps. You decorate your model using attributes and the model binder uses this information to set the ModelState.
public class Customer
{
[Required(ErrorMessage = "First name is required")]
public string FirstName { get; set; }
[Required(ErrorMessage = "Last name is required")]
public string LastName { get; set; }
public string Email { get; set; }
}
On the server-side you would do the usual to check if the model state is valid and if not display validation messages back to the client:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(int id, Customer customer)
{
if (ModelState.IsValid)
{
// TODO: Do whatever...
return RedirectToAction("Index");
}
return View(customer);
}
The form is:
<%= Html.ValidationSummary() %>
<% using (Html.BeginForm()) {%>
<%=Html.EditorForModel() %>
<p>
<input type="submit" value="Save" />
</p>
<% } %>
(I’m using the EditForModel which will automatically generate an input field for each property of the model. If you want finer control you can spit out individual fields or use templates).
Client-Side Validation
Client-Side validation kicks in only if it is explicitly activated in the view. To do this, you need to call EnableClientValidation as shown below:
<% Html.EnableClientValidation(); %>
<%= Html.ValidationSummary() %>
<% using (Html.BeginForm()) {%>
<%=Html.EditorForModel() %>
<p>
<input type="submit" value="Save" />
</p>
<% } %>
By doing this, when the form is generated, the MVC framework will add a call to JS function EnableClientValidation passing in the correct parameters based on the data annotation attributes defined on the model. Last but not least, we need to include 3 Javascript files in the View (I normally put them in Site.Master).
<script src="../../Scripts/jquery-1.3.2.min.js" type="text/javascript"></script>
<script src="../../Scripts/jquery.validate.min.js" type="text/javascript"></script>
<script src="../../Scripts/MicrosoftMvcJQueryValidation.js" type="text/javascript"></script>
Make sure you include the last file, where EnableClientValidation is defined. That’s all there is to it. Once you run this, your app will have both client side and server side validation using the default Data Annotations and jQuery Validator.
Download demo from here
Monday, 5 October 2009 12:10 by
Hadi
We’re all busy these days and sometimes it’s really hard to get any work done with continuous interruptions. As developers we know that it’s hard to get into the mindset that allows us to concentrate on designing a certain class or fixing that retched bug, and any minor incident can throw us way off and place us back at the starting line.
Now I’m sure that it’s not only developers that have this problem. Any type of work the requires concentration probably has the same issues. It just so happens that most of my life has been spent developing software and I speak from experience. Getting interrupted while working on code is a pain!
Avoiding Interruptions
Interruptions can come in the form of emails, telephone calls, instant messaging and recently the more popular Twittering, which I’m finding is substantially limiting my ability to both read or write more than 140 characters. In fact, I’ve written this post via a Windows Live Writer plug-in that injects 140 chars at a time.
There are several ways to cope with this problem. For example when using Outlook, you can suspend the Send/Receive for certain periods of time, or just do what I do and shutdown the damn thing, as much the same with Twitter, Skype, etc. I assign myself periods of a minimum of one hour where I just code, and not deal with email, messages or Twitter. I then take a 5-15 minute break, check all correspondence and go back what I was doing. I find it helps me be much more productive. Other people use techniques such as the Pomodoro or Pair Programming, which personally I find very productive on many levels, but in terms of interruptions. While sitting with someone, it feels kind of wrong to be chatting on Skype or replying to emails while making your coding partner wait. As such, you tend to not do it so often, and avoid potentially embarrassing situations
Avoid causing bottlenecks for others
Increasing productivity is one of the major benefits of avoiding disruptions. Like anything however, there’s always two sides to every story.
Whether working on a team or solo, you tend to interact with people, be it a team member, someone else in your company, customers or 3rd parties you deal with. These interactions are mostly based on emails, IMS’s or phone calls, you know. the same things that disrupt our productivity. Now it’s great for you to be able to control them to increase your throughput, but you need to also bear in mind that what you’re doing is potentially holding up someone else’s productivity.
If someone sends you an email to ask for information about a certain project, or how something should be done or who to contact for a particular thing, these issues might not be effecting your job directly, but most likely it is interrupting theirs.
That is why it’s important to remember that when responding to someone, especially with emails where there is an inherent delay, to always take into account how important the reply is for them, more than for yourself. Does it hold them up? Is it a potential issue?
Obviously sometimes a response requires a little more work, but it’s also very important to communicate this to the originator. Tell them that you need 2 hours to get back to them and you can’t fit it in for another 2 days. The important thing is to not leave people hanging.
Remember, what’s not important for you, might be critical for others. Sometimes I miss the Urgent flag in Gmail. It’s utterly useless for SMTP servers, but it does communicate intent to the receiver of the mail (albeit abused by many).