|
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)
|
|

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. .
 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.
|
|
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.
|
|
|