Tuesday, June 02, 2009

Classic ASP.NET: improper abstractions and ruined REST

http://herdingcode.com/?p=183

1. No one ever anywhere answered the simple question: how to avoid POST operations in a classic ASP.NET when GET operations should be used instead according to a common sense and REST.
POST - for changing data, GET - for reading. No one found any decent way to avoid "Web page was expired"  messages resulting from improper usage of POST. No way to PRG.

To me, this fact alone makes “classic” ASP.NET’s Web Forms approach inappropriate.

2. Yes you can find a workaround for anything, but you’re ending up battling against a framework rather than using it most of the time. And maybe even worse: you’re battling against MS tutorials and books which teach you that ASP.NET-in-24-hours-dataset-no-custom-code-monolithic development.

3. It’s pretty obvious to me, that event-driven model moved from Windows desktop development to Web does not correspond to Request/Response nature of Web and makes programming much more complicated, than even with a plain old ASP. I’d be pretty happy to have lain ASP + C# 3.5 + Intellisense, and believe me, my code would be at the same time more user-friendly and better structured than monstrous code-behind of those ugly master/detail ASP.NET pages.

4. I have nothing against Http Modules, Handlers, etc. They are powerful tools.
But I personally hate Web Forms so much, I think that all those words about Web Forms better in one situations and MVC in another is just a precaution: people understand that MVC is better but are afraid to talk.

Finally, everything is already said in this article and all the comments below.

Monday, June 01, 2009

“Mega” menu? Is it like almost unusable Office 2007 menu?

Usability guru Jakob Nielsen thinks that “mega” menus are good. But is it something similar to Office 2007’s “ribbon” menu?

Office 2007 menu is awful. It's a major step back from a standard and simple Office 2003 menu. Really hard to find what you need, you never sure which main menu bar link to click. My daughter told me to uninstall Office 2007 from her machine because she cannot find anything. If "mega" menu is something like that, I strongly disagree with Jakob Nielsen. The less pictures and other unnecessary graphical elements are in a menu - the better it is.

Wednesday, May 06, 2009

Rob Conery: I Suppose I’ll Just Say It: You Should Learn MVC

http://blog.wekeroad.com/blog/i-spose-ill-just-say-it-you-should-learn-mvc/

Comments under this article are as interesting as article itself.
I only hope I’ll be allowed to write my next ASP.NET project in ASP.NET MVC. I already bought Rob’s book.

Wednesday, February 11, 2009

Write deep Clone(). Forget about ICloneable.

I was chatting with my co-worker about implementing Clone() method for our hierarchy of classes. It's not easy to implement interfaces (think about ICloneable) for class hierarchies. Some tips might be found in Implementing Interfaces at C# Online.NET article, in Implementing Interfaces: ICloneable and IComparable article, and in Advantages of ICloneable? discussion.
As Zach said, it's easier just to implement a virtual Clone() method in a base class and to override it in derived classes as necessary.

I started to look for information about ICloneable and found the following quite unequivocal guidelines:

Caution. Avoid implementing ICloneable. As alarming as that sounds, Microsoft is actually making this recommendation. The problem stems from the fact that the contract doesn’t specify whether the copy should be deep or shallow. In fact, as noted in Krzysztof Cwalina and Brad Abrams’ Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries (Boston, MA: Addison-Wesley Professional, 2005), Cwalina searched the entire code base of the .NET Framework and couldn’t find any code that uses ICloneable. Had the Framework designers and developers been using this interface, they probably would have stumbled across the omission in the ICloneable specification and fixed it.
However, this recommendation is not to say that you shouldn’t implement a Clone method if you need one. If your class needs a clone method, you can still implement one on the public contract of the class without actually implementing ICloneable.

Accelerated C# 2008

Because the contract of ICloneable does not specify the type of clone implementation required to satisfy the contract, different classes have different implementations of the interface. Consumers cannot rely on ICloneable to let them know whether an object is deep-copied or not. Therefore, we recommend that ICloneable not be implemented.
The moral of the story is that you should never ship an interface if you don't have both implementations and consumers of the interface. In the case of ICloneable, we did not have consumers when we shipped it. I searched the Framework sources and could not find even one place where we take ICloneable as a parameter.
x DO NOT implement ICloneable.
x DO NOT use ICloneable in public APIs.
x CONSIDER defining the Clone method on types that need a cloning mechanism. Ensure that the documentation clearly states whether it is a deep- or shallow-copy.

Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries

Tuesday, December 30, 2008

Call a method only if a supplied argument is not Null

Suppose you have a C# method which only works correctly if its parameter value is not Null, otherwise it either throws an exception or returns wrong value. Sometimes you cannot guarantee that a parameter value is not Null, because it was passed from outside, was read from DB, etc. Instead of writing your custom code again and again, which checks a parameter value and only calls a method if it is not Null, it may be more convenient to re-use a common helper method. Overloaded CallIfArgumentNotNull() methods shown below are such helpers. I was somehow inspired by reading this article by Jon Skeet (lazy evaluation) .

    // If a first argument of type int? is not Null, a supplied method (second argument)
    // is called with a first argument passed in and its return value is returned.
    // If a first argument is Null, a default(T) is returned
    // (null for reference types, 0 from Integer, etc.)
    public static T CallIfArgumentNotNull<T>(int? arg, Func<int, T> func) {
      return (arg != null) ? func((int)arg) : default(T);
    }
 
    // If a first argument of type int? is not Null, a supplied method (second argument)
    // is called with a first argument passed in and its return value is returned.
    // If a first argument is Null, a third argument value is returned.
    public static T CallIfArgumentNotNull<T>(int? arg, Func<int, T> func, T defResult) {
      return (arg != null) ? func((int)arg) : defResult;
    }
 
    // If a first argument of type A? is not Null, a supplied method (second argument)
    // is called with a first argument passed in and its return value is returned.
    // If a first argument is null, a third argument value is returned.
    public static T CallIfArgumentNotNull<A, T>(Nullable<A> arg, Func<A, T> func, T defResult)
      where A : struct {
      return (arg != null) ? func((A)(arg)) : defResult;
    }

Monday, December 15, 2008

Android Dev Phone 1 and AT&T

Google recently released completely unlocked Android Dev Phone 1 which is supposed to work with any provider. You pay $25 to register as Android developer and then can buy a phone for about $400. A phone comes with`How to set up your Android Dev phone 1` instruction which suggests that to set up Dev Phone to work with other than T-Mobile providers one needs to open "APN Settings" menu and enter information for a correct provider, using information provided on this `Quick IM` page.

Did someone already successfully set up Android Dev Phone 1 to work with AT&T wireless? Is it really a best and only strategy to type manually APN settings obtained from Quick IM page? Isn't there any more automated way like downloading setup application to a PC, moving to Android Dev Phone 1 through USB and running?

`How to set up your Android Dev phone 1` instruction and Quick IM page also suggest that to use fully Android phone one neds a data plan with GSM service provider. `you need to have a properly configured internet access GPRS account, please note that most operators provide GPRS settings suitable for WAP browsing by default, which is not compatible with QuickIM in most cases. GPRS Internet connection usually requires different settings and possibly an operator activation to work. GPRS settings are often named with "internet" or "web" words in it ; in most cases anything with "wap" in it limits the connection to WAP only.`
A localAT&T agent explained me that such internet GPRS access costs additional $30 per month on top of my normal payments. Pretty expensive...

Update: there are settings for Android Dev Phone 1 to work on AT&T, they were recommended by Jackson Miller on http://groups.google.com/group/android-developers and they work!

Name: AT&T
APN: wap.cingular
Proxy: [Not set]
Port: [Not set]
Username: wap.cingulargprs.com
Password: CINGULAR1
Server: [Not set]
MMSC: mmsc.cingular.com
MMS proxy: [Not set]
MMS port: 80
MCC: 310
MNC: 410
APN type: [Not set]

Thursday, November 20, 2008

An easy way to override Chrome bookmarks

It is quite easy to manually override Chrome “Other Bookmarks” with your Firefox bookmarks:
1) In Chrome, click on “Other Bookmarks” and, if you have any, right click on each bookmark and delete it.
2) Use “Import Bookmarks and Settings”, switch to import from Firefox, clear all checkboxes except ‘Bookmarks’ one and hit ‘Import’.
3) This will keep all imported bookmarks in one ‘folder’, which is actually good, because next time when you decide to override Chrome bookmarks, you will need to delete only one Other Bookamrks ‘folder’ by right-clicking on it.

(On WinXP machine Chrome keeps bookamrks in C:\Documents and Settings\-your-name-\Local Settings\Application Data\Google\Chrome\User Data\Default\Bookmarks file. This is a text file which looks similar to XML. )

Thursday, November 13, 2008

Configuring MS DTC on WinXP, Server 2003, and Server 2008 machines

Our N-Tier ASP.NET (C# 2008 / SQL Server)  application uses MS DTC transactions for database integrity. This allows a transaction to embrace several BL or DL method calls without sharing the same database connection.
A usage is simple:

using System.Transactions; 

using (TransactionScope myTransactionScope = new TransactionScope()) {
  // Do any database related work you need: call methods, open and close connections, update multiple tables.
  // Database integrity is preserved  even if one of methods which update database fails.

     myTransactionScope.Complete();
}

To support MS DTC all servers which run our application (including developers' machines) and servers which host a databases were properly configured. (Configuring developers' machines allowed to work properly with your local copy of application and with a remote database.

1) To configure DTC on Windows XP, Windows Server 2003 machine follow these instructions to open Component Services window and configure DTC.
Make sure that "Use local coordinator" check box is checked on MSDTC tab of computer properties window.
Make sure that "Network DTC access" is checked on MSDTC=>Security Configuration window, that both "Allow Inbound" and "Allow Outbound" are checked, and DTC Logon Account is set to "NT AUTHORITY\NetworkService".
2) On Windows Server 2008 machine it's pretty much the same, except that in Component Services window has My Computer -> Distributed Transaction Coordinator -> Local DTC node, on which you'll need to right-click and choose Properties.
3) After configuring DTC restart your machine.
4) Open Control Panel -> Administrative Tools -> Services and make sure that DTC is set to start automatically and is started.




Reference on using DTC with N-Tier application: http://imar.spaanjaars.com/QuickDocId.aspx?quickdoc=419

Sunday, November 02, 2008

The best of F# and C# -- Nemerle? Scala? various approaches to mixed OOP - functional languages

Today I was pointed out to yet another mixed OOP and functional language: Nemerle. I looked at the Nemerle features and immediately spotted something very familiar, "Probably the most important feature of Nemerle is the ability to mix object oriented and functional programming styles. The top-level program structure is object oriented, while in the body of methods one can (but is not forced to) use functional style. In some programming problems this is very handy." It sounds exactly the same as what is stated about Scala programming language, "Scala is a general purpose programming language designed to express common programming patterns in a concise, elegant, and type-safe way. It smoothly integrates features of object-oriented and functional languages." A main platform for Scala is JVM, but it's CLR variant already exists and is planned to be fully developed.

I think that both C# and Java in their pursuit of simplicity dropped too many functional features which existed in their common parent - C++. I've just blogged about it today. So, both communities felt the need for more functional OOP languages. It looks like that both Scala and Nemerle chose the same approach which creators of Java used: to build up on the base of familiar and wide-spread language in a hope that it gives an immediate advantage of huge number of programmers who are familiar with the syntax and want to try new language. I don't know about Nemerle yet and I still know too little about F#, but Scala language found a very natural and consistent way of combining object oriented and functional features and is even better OOP language than Java.

I think people are absolutely right, when they are saying, that it's hard to catch up with F#, "because the syntax of the ML - derivative languages is just too foreign for those with only imperative language experience". I felt it by myself when I was trying to start learning language using "Expert F#" book, having no prior ML experience.
But there is a flip side: now, when - thanks to an excellent "Real World Functional Programming" book by Tomas Petricek I started to understand both functional concepts and beauty of ML syntax, I feel that more graduate approach taken by Scala (and probably - Nemerle) may in fact postpone real understanding of a functional nature of new languages. It's possible to program in Scala as in "improved Java" and never learn its functional features. And thanks to more steep approach of F# I now better understand and try to pursue functional approach in Scala and better understand ideas behind LINQ...

Learning languages in comparison. How Scala re-introduces what was dropped in C++ to create Java.

An update (30/11/2008): I realize that a title of this post sounds silly. I never tried to say something like "Scala has C++ roots" or so. Scala is "an attempt to come up with a decent statically typed language that is both functional and object-oriented and that interoperates on standard VMs" (Martin Odersky in a comment here). My point is: too much (including some functional features) was dropped when C++ was "simplified" by Java creators. 

Scala allows to pass variable length argument list to a function defined like

def echo(args: String*) =
  for (arg <- args) println(arg)

In "Programming in Scala" authors says that,
'... Thus, the type of args inside the echo function, which is declared as type "String*"  is actually Array[String]'

It immediatelly reminds me C++, which uses similar syntax of passing array arguments. I'm pretty sure Martin Odersky chose asterisk, because it is used in C/C++, although in C/C++ it allows to pass array parameters, not a variable length argument list, and denotes a pointer to a first element of array.

There is definitely a feel, that C++ is more functional language than Java, for example a name of a function is a pointer (reference) variable pointing to a function itself, which allows to pass a function to another function as parameter and return as return value. First-class functions, isn't it?
So, Scala feels partly as a consistent attempt to re-introduce to Java functional features which were dropped when Java creators used C++ to produce new [over?]simplified language.

Personally, I always loved when authors of books described new languages in comparison to existing ones, like Trey Nash is doing in his "Accelerated C# 2008", comparing C# to C++, like David Flanagan is doing in "JavaScript. The Definite Guide", comparing JavaScript to C/C++, and like Bruce Eckel is doing in "Thinking in Java", comparing it to... C++ again. (By the way, Bruce is considering Scala as a next "big" language, which will gradually and partially replace Java the same way Java did to C++.) One fresh and excellent example is "Real World Functional programming in .NET" by Tomas Petricek. This book introduces F# language (a merge of OCaml and .NET platform) and functional concepts in constant comparison to limited functional features of C# 3.0. It helps a lot to understand both F# and functional features of C#. It even helps to understand Scala, because functional concepts are the same in both F# and Scala.
To learn programming languages in comparison is not an easy task. But it is, in my opinion, a most powerful way to obtain real understanding of languages. Footnotes or special text blocks, describing similarities and diffrence between languages make a programming book shine.

Monday, September 15, 2008

VMWare forever!

I couldn't believe my eyes: VMWare Workstation 6.01 took my VM created using MS Virtual Server 2005 R2 Enterprise and run it (Win Server 2003 guest OS) without any problems! Given the fact that the same VMWare Workstation happily runs my Linux Mint guest OS, supports sound, does not require IIS, can be installed on a Linux host OS, for sure takes less resources than Virtual Server (guest OS runs noticeable faster), and, as opposed to MS Virtual Server, it can suspend VM without errors, why bother using Virtual Server at all? (Except that VMWare Workstation isn't free.)

But most importantly: VMWare is not tied so closely to a host OS, as MS Virtual Server is. I installed IE 8 beta (another closely tied product) and suddenly it changed something in a way MS Virtual Server works: I couldn't login to Virtual Server admin side any more. I uninstalled IE 8 beta, but it didn't help. I still couldn't login and because of that couldn't start a virtual machine. Sure, it was something related to permission/security settings, but I couldn't resolve it. Here's where VMWare Workstation came to help. And now I can play with ASP.NET MVC and F# again!