Ingo Rammer Technology Consulting
» IngoRammer.com
» My Books
» Conferences
» Consulting & Services
» Newsletter
 
 
 
» Contact
 

January 2003 Archives


I'd like to write a regular .NET column
January 28, 2003 05:25 PM | Comments (0) | TrackBack (0)

I'd like to write a regular .NET column - a real one, in real media [1], not just in my blog. Either online or in print.

If you are an editor reading my blog and interested in me writing a monthly column for your magazin or portal, please drop me a note.

Credentials: I'm a professional author; have written two books and a number of articles - and I'd like to share both, opinion and experience about .NET applications and enterprise-level application design. Some more reasons why I'm the right one to write a column about these topics can be found at here.

[1] err ... and with real money involved ;-)

Java vs. .NET -- or Why I never participate in these discussions?
January 28, 2003 10:07 AM | Comments (0) | TrackBack (0)

I'm mildly annoyed.

I'm mildly annoyed by constant comparison of .NET vs. Java by folks who don't know the truths about the respective other environment. I read a nice statement the other day which was similar to "Maybe .NET developers should look into Java. Nearly everything which is available there minus EJB is quite similar."

I absolutely second this. But I'd like to go a step further: "Maybe Java developers should actually look into .NET. Nearly everything is quite similar but ASP.NET and Windows Forms could give you a different view about programming in these environments." Is it a better way? Is ASP.NET better than JSP? Well -- at the end of the day, the answer is of course "it depends". Whenever you read a statement similar to "ASP.NET is better then JSP" (or vice versa) you should really take a step back and look at the author's credentials. It might be the case that they actually never ever did a real project in the other environment. There simply is no definite answer to this question. It always depends.

But still -- no matter which one is "better", I'm going to tell you a sad truth: Neither my customers nor most developers care about syntactic sugar like property accessors in C# vs. getSomething and setSomething in Java or events in .NET vs. callback interfaces in Java. I'll even go as far as to say that my clients usually don't care about JSP vs. ASP.NET. They might not even care about the associated implications on long-term maintenance and developer productivity [1].

But what DO they care about? Experience & availability. Both for developers, project leads and sysadmins. Chances are pretty high that in corporations with a number of MCSEs and Microsoft developers, the next step will be ASP.NET and Windows Forms. If however, your customer's business currently runs on Sun Enterprise 15000 machines, you won't see them switch to .NET in a number of years to come. Why? Because they don't have sysadmins capable of running these systems, they don't have developers capable of implementing these solutions, and they don't have project leads capable of estimating the efforts associated with a .NET solution. And -- maybe the biggest concern -- they simply don't have the money for ditching their Sun E15K in favor of a equally or more potent ProLiant. And even if they did -- do you really think that they would render their hundreds of thousands of lines of Java code obsolete and throw them out of the window? Well, these times where money didn't matter are long gone.

Instead of trying to prove to your client (or department, or company) that .NET is "better" than Java by creating lists of points why X is better than Y, I propose a different approach which suits equally well for Java developers and for .NET developers: Interoperate. Maybe you didn't follow the news quite recently, but there is such a thing called SOAP 1.1 which allows you to actually interoperate between the two environments [2]. If you're a Microsoft developer at heart who's working in a Java shop, simply try to sneak in a Windows Forms tool/application. Call your existing Java business logic by means of a web service and show them that it works. Then we can finally sit back from all these discussions and again start to pick the tools which are right for the job at hand.

My name is Ingo Rammer, and I'm a Microsoft developer. I just happened to spend some years in the Java camp as well.

[1] I don't know if you agree, but I definitely think that a seasoned Java developer is actually more productive with JSP than a newly trained ASP.NET developer in his environment.
[2] And no, this isn't marketing BS. It really works. It's just XML. It's just data. There's actually very little which can go wrong.

Third day smoke-free
January 26, 2003 09:40 PM | Comments (0) | TrackBack (0)

NonSmoking

Today is my third day! I feel pretty good and Katja - who never smoked - simply loves it.

Just had to spread the word. Thanks for listening.

Remoting in Mono
January 24, 2003 11:50 PM | Comments (0) | TrackBack (0)

Matt's update re Remoting/Mono:

Currently, the oversimplified not really practical basic remoting is supported.  I recall Miguel saying that a SOAP serializer is either done or mostly done (maybe only in CVS) and that someone has just finished binary serialization for remoting.

Thanks for the information! Cool road ahead ...

MarshalByRefObject
January 24, 2003 11:45 PM | Comments (0) | TrackBack (0)

Jason wonders about some Great mysteries of the CLI

Also - why is [Serializable] an attribute while MarshalByRefObject is a base class? The arguments I've heard are pretty weak. As Mike Woodring points out, deriving from MBRO means inlining of methods has to be disabled.  And who derives from MBRO?  EVERY SINGLE class in the Winforms hierarchy.

As someone who spent a good six months of his life inside the Remoting stack, I certainly do have an opinion on this. At the beginning, I definitely thought the same way. Why the heck didn't they implement yet another attribute for designating an object as a remoteable one? This way, I could easily later flag classes deeper down in my class hierarchy to be remoteable. And that's the very answer as well. This just isn't possible.

Let's say you have the following method:

public void foo(bar x)
{
   x.baz()
}
And you have an inheritance hierarchy of [System.Object]<-[bar]. In this case, the JIT could inline the call to baz().
 
If you'd use attributes to designate MarshalByRef (or "proxyable") semantics, you could then extend the hierarchy: [System.Object]<-[bar]<-[foobar] and flag foobar with this attribute. Bad thing. The JIT now must not inline the call to baz().
 
The only possible way to solve this is to have [System.MarshalByRefObject]<-[bar] because this way, the JIT knows right from the start not to inline the call to baz() and everything will be fine.
 
Still - why does every class in Winforms inherit from MBRO? Well, MBRO also conveys the point that "it doesn't make sense to ever marshal me by value." This basically means that the object is somehow bound to a resource on a single machine, like an hWnd for example. So much for Windows Forms [1].

I however also remember a discussion with another speaker at one of the conference (not sure if it was Mike or Peter) in which we were talking about our opinions that the name "ProxyableObject" would have been better to convey the correct meaning. Heck, it isn't about marshalling by reference - it's about proxying. And no, I don't think that these are the same things. A MarshalByRefObject would have to be proxyable but any random proxyable object could just exist without any marshalling at all. I could simply create a proxy (i.e. a custom RealProxy), flag my class with a ProxyAttribute and see: I get a proxy instead of a real object whenever I create a new instance of the class.

So in fact, ContextBoundObject should have been called CustomProxiedObject. It's not about contexts - it's about an object supplying its own proxy. Creating or checking contexts is just the work of one very special kind of proxy. It could do many more things - like simply intercepting method calls and providing for some AOP semantics.

[1] Weird idea: maybe that's a good thing. You are normally supposed to check ctl.InvokeRequired (and if true, use ctl.Invoke() instead of directly manipulating the UI) when working with multiple threads. You could write a simple, generic proxy which you could use in front of any GUI control, and which would do this for you automatically whenever you call any method or access any property. Hey, just talking about getting rid of some code.

On Linux, Open Source and the World
January 24, 2003 08:36 PM | Comments (0) | TrackBack (0)

Will I ever "switch" to Linux/Mono? No ... seriously, I really like Exchange server - but you already knew this. Actually, Exchange is just a sample: From my general experience, it's simply easier to interop with different applications and servers when running on a Windows box.

Oh, and yes, I know that there are people who fear "data-lock-in" when using Microsoft products. My opinion on this topic is a little bit different. I believe that whenever someone tells you something like this, you shouldn't believe him too much but instead try for yourself. Actually, there are few (if any) products in the Microsoft space which don't either offer the necessary APIs to access your data or for which there aren't XML based means to access it. This fear of lock-in mostly comes from people who never worked in this space. Fear is a sign of nescience. This is however not only true for the open source folks. I know quite a number of guys on my side of the fence who fear Linux and open source software in a similar way. 

Don't fear it - use it. That's the only way which allows you to judge for yourself. 

Mono is getting serious
January 24, 2003 08:25 PM | Comments (0) | TrackBack (0)

Matt has been hanging around at LinuxWorld and reports on the state of Mono:

C# is done, VB is 70% done, and JavaScript is 50% done.  This is good.  Miguel demonstrated an almost unmodified version of iBuySpy that was only really slow because it was connecting to an MSSQL server in Spain over 802.11b. In theory, you could write an ASP.NET web application today and deploy it on a Linux server using Mono. [...]

Overall I was impressed by the state of Mono and the demos.  It's awsome to be able to take a Microsoft demo app out of the box and run it using Mono.

Wow. That sounds pretty serious. I guess I actually have to fire up a VMWare to install a recent Linux distribution on it and play a little. Anybody knows about the current state of ASMX support on Mono?

Clemens rocks
January 24, 2003 06:19 PM | Comments (0) | TrackBack (0)

From the "While you've been in bed"-department: Clemens is working on "a pretty radical extension for Enterprise Services and COM+ - it's actually more a "new feature set" than a tool or wrapper.". I really hope that he succeeds at squashing the GC related bugs. For those who dare to know, let me rephrase Clemens [1]: we're talking about interception similar to IMessageSink, but this time for EnterpriseServices. And no, you won't need a new version of COM+ and no, you also won't need a new version of .NET or Windows. It seems as if support for this kind of functionality is already available. But as Clemens puts it: it's writing code based on analyzing hex-dumps

If you just wondered ... yes, Clemens rocks. Hacking things like this is just a slight little bit above my knowledge: while the tough guys played C++ and COM in the 90s, I did VB and Java. On the other hand, there are actually very few things which make me regret this - it's just that Clemens' EnterpriseServices extension is certainly one of them. It's so hard to realize that there are things in a technology (which you otherwise know pretty well) which you'll never fully understand [2].

[1] Hey, I'm not saying anything more than he already did. I promised.
[2] Oh yes, I've seen the source. And it sounds pretty reasonable when Clemens explains it. I however still don't understand it at a level which would allow me to re-create or even start re-creating it - and I quite likely never will. I never knew the glory days of C++ ;)

What a week ...
January 24, 2003 06:12 PM | Comments (0) | TrackBack (0)

What a week: been in bed, sick, Sunday to Thursday. Argh, I even had to cancel a conference gig. This pretty much sucks - I'm really sorry about it.

Gentile 4.0
January 24, 2003 06:09 PM | Comments (0) | TrackBack (0)

Congrats Sam and Sue!

By the way: will I get the chance to meet the four Gentiles during WIN-DEV later this year?

OutBlog in Switzerland
January 18, 2003 09:51 AM | Comments (0) | TrackBack (0)

I just found two .NET bloggers in Switzerland who also happen to use OutBlog:

Hey ... I usually spend a week each month in Zurich. How about dinner? Next time will be from 2/10 to 2/14.
Training and Consulting
January 12, 2003 02:47 PM | Comments (0) | TrackBack (0)

Since Jan 1, 2003 I'm in progress of selling my previous company to my partner and I'm again working as an independent consultant and trainer. You can hire me throughout the European Union and Switzerland for .NET Consulting and Prototype development, or get your hands dirty at one of my Distributed .NET Courses which I can deliver right in your offices.

And frankly, when it comes to distributed .NET applications, I really know quite a bit to teach ;-)

The specified module could not be found.
January 12, 2003 09:05 AM | Comments (0) | TrackBack (0)

"The specified module could not be found." - This text shouldn't be too unfamilar for the ones of you visiting my weblog in the past few hours.

If anyone is interested in the "why's and how's" of this bug:

  • It is caused by the COM/Interop call to CDO.Message
  • cdoex.dll was registered in the wrong place
  • It was registered in "c:\inetpub\develop~1\exchan~1\bin" - and I have to admit that I don't yet have the slightest clue on the following points:
    • Why it has been registerred there even though it must have been registered in the correct location ("C:\Program Files\Common Files\Microsoft Shared\CDO") before.
    • Why the file doesn't exist in "c:\inetpub\develop~1\exchan~1\bin" anymore. (Actually, that's not true. The whole folder exchan~1 doesn't exist anymore.
    • Why the program (hint: usual suspect is VS.NET for obvious reasons) which finally deleted it from this folder didn't unregister it. (The last one is actually good. If the file would have been correctly unregistered, I wouldn't have been able to find the bug that quickly)
    • Why the heck this whole thing turns up at some time after I run 100 builds of this system without any problem.
I guess there must have been a lot of coincidences which triggered this bug. I guess I'll file it in the unreproducable, but very nasty-department.
Version 0.1 of OutBlog (the application formerly known as ExchangeBlog) released
January 09, 2003 11:36 PM | Comments (0) | TrackBack (0)

Let's spread the word: Version 0.1 of my highly anticipated (well, at least by the two people who read this weblog) Outlook and Exchange 2000 powered weblog toolkit OutBlog has been released. More information (and a sample blog & download package including source code) is available at http://OutBlog.IngoRammer.com.

Modular Applications
January 07, 2003 01:06 PM | Comments (0) | TrackBack (0)

Clemens: A modular application without well-defined extensibility points is not modular.

I'd even go one step further: A modular application which defines extensibility points without using them in the actual application is not modular.

Let me elaborate on this a little: Suppose you're designing a great, modular, extensible application. Let's say it's about customer relationship management or such. To provide for real extensibility, you allow all business operations and maybe even low-level operations (create, read, update, delete) to be intercepted (f.e. by chain of plug-ins). However, the "real" persistence to your database and the "real" business operations are hard coded and don't use the same extensibility mechanism. Obviously this is the right approach because you wouldn't want someone to change this core behavior anyway, right?

Maybe, but more likely it isn't. The problem in this case is that your application can do substantially more than what you allow for extensibility elements. But as long as there's no plug-in available, you don't really know if your extensibility points allow you to solve all possible future requirements (and remember: You design extensibility hooks for future requirements which you can't possibly predict right from the start.)

What could happen in this case is that some third party would need access to some functionality which is buried in the "core", the inaccessible framework of your application. Maybe you didn't pass a parameter, missed some state information or simply forgot about a small flag. You cannot notice this until someone actually starts to use your extensibility hooks.

To satisfy your customer, you'll have to change or extend the extensibility hooks in this case. That's something which should be avoided like the plague as it might cause some serious headaches for other plug-ins which existed before this change.

So how could you work around this potential problem? Use the extensibility mechanisms right from the start. Design the core of your application based on extensibility elements. Don't hardcode. Always plug. Always. Everything.

Simple example: When someone right-clicks an object in your application, he will get a context menu. This menu is filled by some "core" options ("Delete element"), and other additional functionality which can be provided by plug-ins ("Convert to XML", "Send by fax", ...). In this case, you should really fill all the default (core) options using the same extensibility interface. I.e. you register a class of your main application as a plug-in as well.

When you extend this sample to cover not just simply context menu handling but also business logic and database logic, you can be absolutely sure that whatever your main application can do, could also be done by a plug-in. This is 100% extensibility. Guaranteed.

Conferences 2002
January 07, 2003 12:33 PM | Comments (0) | TrackBack (0)

None of this is real. All made up. Innocent until proven guilty. Or such.

As Ted started with some conference gossipping, he reminded me that I really wanted to spread some "Best Of Conferences, 2002" gossip and photos as well. Ok ... let's get ahead.

First, let me assure you that conference speakers are hard working people. We don't do this for fun. Really. .

Lifestyle
Conference Lifestyle?

Nick also taught us one thing this year: How to approach Germany's favorite pop star in two easy steps. (He had one small advantage: he didn't know about her stardom. She was just a nice girl.) First step: Pay her compliments: "Nice pants. Are they custom made or did you buy them like this?". Second step (after the others told you whom you've just been approaching): Catch her when she gets down from the elevator, tell her that you really don't like pop music at all, but instead prefer opera, and finally get some other geek to take a photo:


Nick, Sarah, Ted

Apart from the fun, we definitely tend to have some very enlightening, peaceful discussions. As we are all quite level-headed people, we can always leave our religious opinions and emotions out of discussions:


Miguel: "Can't you finally see that CORBA is better than Web Services?"

On the technical side, we finally found about the reasons why wireless LANs have been invented:


Wireloss LAN ;-)

But approaching pop stars hasn't been the only thing learnt this year. Here's a famous .NET weblogger getting ready to show his Hula Hoop skills:


Peter at the Hula championship

Another thing we experienced is that sun doesn't always shine in Walt Disney World, FL:


John, Annette, Jason, Katja

The good part is that it basically took only a couple of minutes to clear up again:


Jason, Annette, John

The most amazing part of this years conferences? I guess it was a bet made after Peter's Hula performance in which he persuaded Ted: "You don't dare to wear this hat at your talks tomorrow" - "Sure do I".


Ted's famous hat

You know what? He really did.

    
Ted speaking (about running Apache with .NET, I believe)

Ok folks, as you can see, I really had a great time speaking and hanging around at last year's conferences. Looking forward to meeting all of you again this year!
 
And remember: None of this is real. All made up. Innocent until proven guilty. Or such.
ClearType and Noticeable Delays in General
January 07, 2003 10:16 AM | Comments (0) | TrackBack (0)

Peter and John bemoaned the loss of ClearType when switching to the Mac. Well, I guess I'm simply too 20th century in this regard. I just can't stand ClearType. I played with it, turned it on for a couple of days, turned it off for another couple, turned  it on again, tuned it, etc. and came to the conclusion that it just doesn't cut it for me.  

I'm a performance manic [1]. I really like XP but I'm currently running on a 1700Mhz box and recently booted up my old 600Mhz Laptop to notice that it loads the start menu way faster than my current machine. After some investigation, I switched my XP back into W2K-look-alike mode (apart from the start menu layout style) and checked "adjust for best performance" (the most important XP setting ever; located conveniently at MyComputer -> Properties -> Advanced -> Performance/Settings). My system rocks after changing this setting! I really can't stand it if a menu takes a noticeable time to open, and after changing this setting I an got instant-on start menu and "All Programs" menu. That is, no noticeable delay when opening the menus.

It's the same story with ClearType for me: it slows my system down to a point where I can notice it. But maybe I'm a little bit oversensitive in this regard: I once had a Logitech radio mouse/keyboard. I ditched it because the keyboard was slower in responding than any wired keyboard. Yes, I really noticed it. Nobody else did though.

[1] That is, I don't play games on my PC, so I don't really have to run the most current hardware. I just want to get the best possible performance out of the existing hardware.

Peter's back!
January 07, 2003 10:11 AM | Comments (0) | TrackBack (0)

Peter's back. Great!

Use the Tools. Don't reimplement
January 06, 2003 11:47 PM | Comments (0) | TrackBack (0)
Gordon: In the space of a week, Ingo and Greg have transformed MS Exchange and Outlook into a competitor for Radio. Who would've guessed? 

I think that the most important lesson learnt was "Use the tools. Don't reimplement". Total development time was < 20 hours.

I really have to try Greg's aggregator together with this tool. Hey Greg, we could even add a custom action to your Outlook forms which would post the entry to the weblog. Basically the same way Radio does when posting from its aggregator.

Exchange Blog - Some Architectural Infos
January 06, 2003 10:52 PM | Comments (0) | TrackBack (0)

I got quite a number of questions regarding details and plans about my ExchangeBlog.

First and foremost: I'm a consultant. I actually don't have the time to create a product for sale. What I'll do instead is talk a little bit about the technology behind it, give the source code away for free and hope that someone who likes it engages me for a consulting gig to create a custom intranet which can be managed using solely Outlook and which is powered by Exchange Server and ASP.NET. Content management for the masses - using the tools you already know ... or such ;)

Ok Ingo ... stop dreaming, back to reality.

The foundation for all of this comprises of three things: a custom Outlook form, some custom ASP.NET code, and an Exchange server sitting at dotnetremoting.cc. The latter is also quite likely the limiting part - when adding up the costs for the Exchange Server license, I've basically created The World's Most Expensive Blogging Tool. If you however - like me - already use an Exchange Server which is licensed for this kind of use, then everything should be fine. This might be especially interesting for Intranet scenarios ...

The good news is: it's actually pretty easy. As you probably know, an Outlook custom form of type IPM.Note can contain a body text formatted in HTML. What I therefore did was to create a new form of this type (called IPM.Note.WeblogPost) which re-uses (actually re-defines, but that's a different story) some Exchange folder fields for blog-specific information. I can currently enter "Subject", "Publication Date" (also future dates. In this case, nobody will see the post until the given date has been reached), and "Sensitivity" which basically designates whether the post is public or not (interesting for partly finished stories or such).

The really great thing happens when you add images or other information to your post (using just Outlook). In this case, the image will be uploaded to your Exchange server from where it can be downloaded using a simple http URL. As I didn't want anyone to directly hit my Exchange server, I analyze the body of the message while rendering it, download the attachment and store it in a cache on my web server (just right-click on the previous day's image to see this).

Fortunately enough, Outlook/Exchange already store the complete body text in HTML, so that I just need to tidy it up a little(remove the <HTML>, <HEAD>, etc. tags) and reformat MIME Urls (like <img src="cid:12345@789" />) by downloading the images to the said cache before outputting the HTML. All of this (downloading the images, parsing the MIME message, ...) can be accomplished by using CDO, CDOEx and ADO.NET. That is, you don't have to manually split any MIME message yourself or such.

To render the posts (current weblog, archive or single day), I created a single ASP.NET page which accepts the parameters "day" and "archive". Both of which are optional and, if present, have to be sent in the format DDDD-MM-YY (or actually, in any format which can be used by DateTime.Parse()). If no parameter is sent, it will render the current weblog (10 days of posts) else it will either render a monthly archive or a single day. If the parameter is in an incorrect format, it will simply render the current weblog instead.

The rendering itself is done by a helper class, and the result will simply be put into an ASP.NET Literal control which I placed on my page template. The resulting page is then cached using ASP.NET output caching (60 seconds, varying by parameters "day" and "archive") to reduce the Exchange server's load. Or more correctly, to reduce the chance of any denial of service attack on my Exchange server. No matter how often you click "reload", I'll hit the server only once a minute for each page.

In total (excluding the HTML code which can be drag and drop-generated), we are talking about a massive 500 lines of code for a blog tool which supports the following:

  • WYSIWYG HTML editing, both paragraph based and character based formatting (of course you prefer the first, but just in case ;-))
  • Automatic uploading of Images, URLs, ...
  • Spell checking
  • RSS (that's already included in the 500 lines)
  • Offline support, on-demand synchronization with server
  • Macros
  • Full text indexing
  • ... and whatever else Outlook and Exchange offers ...
So ... what did I learn while implementing this piece of software:
  • Leverage the tools which already exist. No need to program everything on your own.
  • If you create an application which you later want to share, design it multi-layered right from the start. (Now, I actually have to refactor most parts of it because of the utter uglyness of the code.)
  • If you create an application which you later want to share, comment your code right from the start.
 
This blog is powered by Exchange Server
January 05, 2003 01:53 PM | Comments (0) | TrackBack (0)

Ok, I finally got the time to clean up the rest of my "in-development" version of dotnetremoting.cc, therefore: This Blog Is Now Powered By Exchange Server.

Which adds some pretty nice features. I can, for example, simply take a screenshot and drop it in the Outlook form used to write my posts. I don't have to care about uploading, ftping, etc. It's managed for me automatically. Pretty cool, huh?

Here's the proof:

Update [Jan, 9]: The application (including source code) is now available at http://OutBlog.IngoRammer.com






© 2002, 2003 by Ingo Rammer (ingo@ingorammer.com). Information is provided as-is and is subject to heavy changes due to its pre-release character.