Archives

Archives / 2003 / March
  • Great Article On Data-Binding To Custom Types

    Here's a great MSDN article on data-binding to custom types and collections of those types. It covers topics such as:

    Overall I found the coverage of the features in this article to be excellent and a great extension to the SDK's basic documentation on the subject. I definitely recommend it to anyone who is writing their own business objects which they wish to use in data-binding scenarios.

    Read more...

  • McNealy says .NET is a joke

    On a tour of Asia, the Sun Microsystems' CEO hits out at rival Microsoft, saying that viruses are a feature in .Net Microsoft and that Java is tops for developers. [CNET News.com]

    Umm... yeah. Can you say FUD?

    The only known .NET related virus is W32/Donut and it's so lame it's not even worth wasting bandwidth discussing any further. Get back to us when you can actually show us a managed .NET virus.

    Update:

    Phil Scott pointed out W32/Sharpei@MM in the comments . Thanks Phil, I had forgotten about this one. So that makes two, but technically it takes advantage of the same exploit: hijacking the executable bootstrap generated for .NET console/winforms application images. Again it's so lame that it's called a C# virus when really it has nothing to do with .NET (let alone the C# language). In fact the article even mentions that the user doesn't even need to have .NET installed. Hello?? Doesn't this set off a flag in intelligent peoples' minds? I remember a time when certain Java compilers/VMs offered the option to generate a bootstrapping .exe too. The same exploit could be leveraged on those as well.

    Read more...

  • Events: How They Work In C# and General Component Design Techniques

    I just finished an MVC implementation for WinForms as a tutorial for whomever and as a walkthrough for myself to see if I could find a nice tidy way to organize my ever increasingly Forms classes. I noticed something I just can't figure out.

    When publishing an event that noone subscribes to I get a nullreference exception. There are no way (as I can see) to instantiate the Event in and make sure it's not null so I had to go like this:

    ... code snipped for brevity ... (ed.)

    Is this really the only way to do this? Have I missed out about something with publish/subscribe? It should be possible to scream although noone is actually listening..

    [mads studentblog]

    Yup. That's just the way C#'s event keyword works when used in it's abbreviated form. An event is really nothing more than a glorified multi-cast delegate. When defining an event in .NET you're essentially just specifying metadata on your type that says "Hey, I have an event called 'XXXX' and here are the two methods you can use to subscribe and unsubscribe.", much like a property is just metadata that points to a pair of get and set accessors. So when you define an event in C# using the abbreviate form the compiler is generating add and remove event handler methods for you behind the scenes. The implementation provided will defer instantiation of the event delegate until the first subscriber to the event invokes the add_XXXX event subscription method. Therefore, you must always test your event delegate for null before invoking it.

    Now, something that a lot of people who are new to C# don't realize is that you can take full control of the event registration methods yourself by taking the event declaration a step further, like so:

    public event EventHandler MyEvent
    {
        add
        {
            ...
        }

        remove
        {
            ...
        }
    }

    You can more about the C# event keyword right here in the SDK.

    The prime example of custom event subscription methods is the Windows Forms Control architecture which makes extensive use of this technique to reduce the potential overhead associated with the many of events on control instances that are likely to never even be subscribed to. The architecture accomplishes this by storing the delegate instances in an event hashtable on the control instance (see Component::EventHandlerList). The hashtable is keyed by a static object references representing each event. Should someone subscribe to a particular event, the delegate is created at that point and cached for the control instance. This can signifigantly reduce the size of each control instance by saving the memory of N delegate member variables weighing in at the cost of a reference variable each. When you consider the fact that the base Control class has 58 events itself and the cost of a reference variable in the Microsoft .NET runtime on the x86 platform has a native size of four bytes (32-bit pointer) that's 232 bytes saved per Control (or subclass) instance. This is a pattern that all component developers should take into consideration when they hit the optimizing stage of their product. This pattern and more details about events in .NET are discussed here in the SDK.

    Read more...

  • Taking Custom Configuration Sections A Step Further

    Something I've found infinitely useful is custom configuration sections By using custom configuration sections, you are allowed to store a richer amount of information in the application config file, than when you simply add values to the <appSettings>section.

    To add a custom config section, you must do 2 things: 1) declare the section group and section in the<configSections> portion of the app.config file, and 2) add the new sections to the config file.

    [.NET Brain Droppings]

    Yup, it's cool, but it gets even cooler when you start writing your own configuration section handler implementations. The beauty of the configuration architecture is that it's completely extensible. To hook into the deserialization process all you need to do is implement a custom IConfigurationSectionHandler. The first time someone requests your named section via ConfigSettings::GetConfig, your implementation of IConfigurationSectionHandler::Create will be called and handed an XmlNode which you can then parse and turn into your own typed configuration object. This just opens infinite possibilities and builds upon the power of XML when it comes to embedding documents.

    The prime example of a custom section handler that a lot of people seem to be into lately is the all purpose XmlSerializer based configuration section reader which deserializes sections into .NET types using the power of the XmlSerializer.

    The final thing to remember about the configuration system is that it's heirarchical. Enterprise settings, Machine settings and Application specific settings are all unioned together to present a unified configuration to each application when it runs. ASP.NET takes this a step further allowing another steps in the heirarchy according to virtual application directory structure.

    Read more...

  • Solid Advice On Preferring Overriding To Base Class Event Registration

    I can't remember the last time I've been handed source code for a Form- or UserControl-derived class that didn't include a handler for its own Load event. Why is this? Sadly, I know the reason... [Shawn A. Van Ness's Blog]

    Some solid advice from Shawn. He explains the common WinForms scenario, but it really applies in any component inheritance scenario. For example with ASP.NET, it's mainly the Control::Init and Control::Load events that people end up doing this with. I've tried to explain it on DOTNET mailing lists on a couple of occasions, but I still see people doing it from time to time. As Shawn points out, it's not really a serious problem, but it's just not the best practice. With .NET, we're living in an OO world, we should take advantage of it and prefer method overriding in these scenarios.

    Oh... and on the flip side of the coin, whenever you're designing a component, make sure and follow the recommended design guideline of defining a protected virtual On<EventName> method that inheriting classes can override.

    Read more...

  • Understanding SOAP

    There's a new article up over on MSDN under the XML Web Services section entitled Understanding SOAP. The author is none other than DevelopMentor XML guru Aarron Skonnard. In the article, Aarron covers SOAP from a pure XML protocol perspective; no specific client/server implementation is discussed. Next to only the specification itself, this is the best piece of reading anyone looking to learn the protocol should check out.

    Read more...

  • VS.NET Binary Resource To Base64 Macro

    This macro was created in response to a thread on the DOTNET-WINFORMS list where someone was wondering how to work with XML resource files independent of the Windows Forms/Controls editors. Basically all the macro does is allow you to select a file which it then opens, converts its contents from a byte array to a Base64 and places the resulting string on the clipboard for you to paste wherever you like.

    Read more...

  • VS.NET Google Macro

    I wrote the following macro a while back as a response to a question about searching Google from within VC6 on the ATL List. Simon Fell responded and pointed out that he had written an add-in for VC6 to support this. I felt like learning the VS.NET object model at the time so I took a few minutes and drafted this up. It's really simple, but at least it's a start. I suppose with the new Google API I could get a lot fancier and even have my own search results window.

    Read more...

  • C# for vs. foreach Over An Array

    This article coincides with this weblog entry and is intended to show the compiler differences between enumerating the elements in an Array using a manual for loop vs. using a foreach loop.

    for approach


        MyStruct[] myStructs = new MyStruct[3];


       for(int index = 0; index < myStructs.Length; index++)

        {

            Console.WriteLine("{0}", myStructs[index].MyField);

        }


    .method public hidebysig instance void  Test1() cil managed
    {
      // Code size       55 (0x37)
      .maxstack  4
      .locals init (valuetype Test.Class1/MyStruct[] V_0,
               int32 V_1)
      IL_0000:  ldc.i4.3
      IL_0001:  newarr     Test.Class1/MyStruct
      IL_0006:  stloc.0
      IL_0007:  ldc.i4.0
      IL_0008:  stloc.1
      IL_0009:  br.s       IL_0030
      IL_000b:  ldstr      "value of MyField for MyStruct at {0} is {1}"
      IL_0010:  ldloc.1
      IL_0011:  box        [mscorlib]System.Int32
      IL_0016:  ldloc.0
      IL_0017:  ldloc.1
      IL_0018:  ldelema    Test.Class1/MyStruct
      IL_001d:  ldfld      int32 Test.Class1/MyStruct::MyField
      IL_0022:  box        [mscorlib]System.Int32
      IL_0027:  call       void [mscorlib]System.Console::WriteLine(string,
                                                                    object,
                                                                    object)
      IL_002c:  ldloc.1
      IL_002d:  ldc.i4.1
      IL_002e:  add
      IL_002f:  stloc.1
      IL_0030:  ldloc.1
      IL_0031:  ldloc.0
      IL_0032:  ldlen
      IL_0033:  conv.i4
      IL_0034:  blt.s      IL_000b
      IL_0036:  ret
    } // end of method Class1::Test1

    foreach approach


        MyStruct[] myStructs = new MyStruct[3];
        foreach(MyStruct aStruct in myStructs)
        {
            Console.WriteLine("{0}", aStruct.MyField);
        }
     
    .method public hidebysig instance void  Test2() cil managed
    {
      // Code size       59 (0x3b)
      .maxstack  2
      .locals init (valuetype Test.Class1/MyStruct[] V_0,
               valuetype Test.Class1/MyStruct V_1,
               valuetype Test.Class1/MyStruct[] V_2,
               int32 V_3)
      IL_0000:  ldc.i4.3
      IL_0001:  newarr     Test.Class1/MyStruct
      IL_0006:  stloc.0
      IL_0007:  ldloc.0
      IL_0008:  stloc.2
      IL_0009:  ldc.i4.0
      IL_000a:  stloc.3
      IL_000b:  br.s       IL_0034
      IL_000d:  ldloc.2
      IL_000e:  ldloc.3
      IL_000f:  ldelema    Test.Class1/MyStruct
      IL_0014:  ldobj      Test.Class1/MyStruct
      IL_0019:  stloc.1
      IL_001a:  ldstr      "{1}"
      IL_001f:  ldloca.s   V_1
      IL_0021:  ldfld      int32 Test.Class1/MyStruct::MyField
      IL_0026:  box        [mscorlib]System.Int32
      IL_002b:  call       void [mscorlib]System.Console::WriteLine(string,
                                                                    object)
      IL_0030:  ldloc.3
      IL_0031:  ldc.i4.1
      IL_0032:  add
      IL_0033:  stloc.3
      IL_0034:  ldloc.3
      IL_0035:  ldloc.2
      IL_0036:  ldlen
      IL_0037:  conv.i4
      IL_0038:  blt.s      IL_000d
      IL_003a:  ret
    } // end of method Class1::Test2

    Read more...

  • Is COM Interop Fundamentally Flawed? IMHO, No.

    Prefix: Sam Gentile posed the question Is COM Interop Fundamentally Flawed? to which this is a response.

    First, I need to be completely honest. I've been down this road before. I've essentially been working with P/Invoke and COM interop, amongst other .NET concepts, since 1997. "How the heck is that possible?" I hear you ask. Well my friends, allow me to let you in on a little technology called Java, more specifically, Microsoft's implementation and extension of it known as J++. Most of you probably heard about the trial between Sun and MS, well these were the technologies at the very heart of the debate.

    You see, the CLR and a majority of it's features stem from the MSJVM. Back then P/Invoke was called J/Direct and since there was no concrete concept of attributes, Microsoft invented a special commenting style that enabled similiar feature. They were lovingly referred to as "@dll" and "@com" directives. The @dll directives were used for mapping native methods to a Java signature, as well as mapping native structs to Java classes. The @com directives were used for mapping Java interfaces and classes to their respective COM interfaces and coclasses. The COM Interop portion of J++ took the nickname Java/COM. We had JCWs (Java callable wrappers) and CCWs (COM callable wrappers), .NET has RCWs (Runtime callable wrappers) and CCWs. Tools wise: Java/COM had JActiveX.exe, .NET has Tlbimp.exe. We had Javatlb.exe, .NET has Tlbexp.exe. We had delegates, .NET has delegates. We had the beginnings of a declaritive and programmable security model which was somewhat like .NET's System.Security.CodeAccessPermission and related classes. We had com.ms.wfc.ui *part of the Windows Foundation Classes libraries), .NET has System.Windows.Forms. Not many people bought into the marrige of Java and COM, but those of us that did loved it to death and had a very close relationship with the developers at Microsoft that were keeping the marrige alive. I've said it before and I still maintain that the Java/COM team was one of the best groups within Microsoft that I've ever worked with. Oh, and guess who some of the major players on that team were: Anders Hejlsberg who is primarily responsible for C# and Brad Merrill who is now Program Manager on the .NET Developer Platform team. So it really is no surprise that so much of the technology in .NET was inherited from J++, in fact check out this letter (dated 2001) where Anders says the technology started four years ago. Hmm... that would be 1997 when J++ was just going beta. Coincidence? I think not! ;)

    So, what does all this have to do with Sam's question? Well, it's simple really, Sam's same question was at the center of many debates back in the Java/COM days as well[1]. The implementation was exactly the same. A JCW would go out of scope, but the underlying COM object would not be IUnknown::Release'd until the GC did it's duty and called the finalizer on the wrapper. To take better control of COM object lifetime we had a method just like System.Runtime.InteropServices.Marshal::ReleaseComObject, it was com.ms.com.ComLib::Release[2].

    The fundamental problem with COM interop in both runtimes is that you're mixing garbage collection with deterministic finalization. For what COM interop is out of the box, I think it is good enough. For more complex scenarios where you need to control the lifetime of the underlying COM resources, both runtimes provide a releasing mechanism. Yes, you have to take a little bit more control in these scenarios. Yes you have to have use a try/finally pattern with a ReleaseComObject call to clean up your resource. It's not the end of the world. Everyone knows this now, it should be common knowledge learned easily by reading a chapter in a .NET book on COM interop or by searching through newsgroups and mailing lists and now by reading community weblogs.

    Now as a final observation, I will say that we do have a new pattern in .NET that we did not have in Java/COM. That pattern is the IDisposable pattern. Early on when .NET was in it's beta2 days and IDispoable had just been defined I wondered why all RCWs didn't inherit from IDisposable where the Dispose implementation is provided by System.__ComObject and looked just like this:


    public void IDisposable.Dispose()

    {

        System.Runtime.InteropServices.Marshal.ReleaseComObject(this);

    }

    If this were the case, we could dispose of COM objects using a familiar .NET pattern taking advantage of whatever our chosen language provides for us to handle the pattern. In C#, a COM object could be used deterministically just by using the following syntax:


    using(MyComObject myVariable = new MyComObject())

    {

        // use myVariable here

    } // C# ensures IDisposable::Dispose is called here exception or no exception

    Maybe in v.Next of .NET we can hope such an adjustment is made.

    [1] Search the Java/COM list archives for "(Release) or (COM Leak)" and you'll see what I mean. ;)
    [2] Believe it or not, I could not find the documentation page for this online anywhere. You can still download the Microsoft Java SDK though.

    (ed. note: All links for this article were found via Google and/or Microsoft's MSDN online)


    Read more...

  • Mozilla 1.0 Commentary

    Can I just say how happy I am that Mozilla 1.0 is finally here? I've been writing DHTML apps for a long time. Now, when I say DHTML I mean truly interactive content, more along the lines of what you usually see in flash apps or Java applets. One of the first DHTML apps I wrote was an intranet website for Microsoft's New York Marketing group. I built it during the beta of IE4.0 and launched the app shortly after IE4.0 went gold. I published a quick overiew of it along with some screenshots back in 1999, perhaps I can get more into the implementation sometime, but sufficed to say that it was an awesome experience. The HTML DOM was a beautiful thing even back then when it wasn't 100% standardized and now that, more recently with IE5+ and Mozilla 1.0, the HTML DOM is layered on top of the core XML DOM it's even more beautiful.

    Anyway, back to Mozilla in a second, but first I need to set the stage:
    Today, I work for Mimeo. I won't bore you with a sales pitch here, you can check out the site if you'd like more info about us, but a mission critical part of our offering is the ability to dynamically create and see your documents online. To do this we developed a two step wizard consisting of two "controls" which allow you to dynamically combine files and then format the overall document. For the first piece, combining, we had to develop two completely different versions of the renderer for Netscape 4.x and IE4+ (we do not even bother to support NS6.x as it was a complete nightmare and never got anything we threw at it quite right). IE4+ allowed us to dynamically add content such as table rows, divs, whatever. Netscape 4.x, while it did allow you to write dynamic content, forced you to rewrite everything to the document and the performance and stability was just abominable. For the second step, formatting, the content of the page was relatively static. No new elements need to be created, all we do is change image sources (HTMLImageElement::src), show/hide divs (ElementCSSInlineStyle::visibility), and change text (IHTMLElement::innerText in IE and document.open/writeline in NS4.x). The rest is pure JavaScript business logic which has run in NS4.x, IE4+, and Mozilla1.0 browsers almost flawlessly with no browser detection whatsoever for the past three years. So, hurray for one standard (albeit 3.0 JavaScript)! So, I think it's fair to say we have a pretty complex application compared to most DHTML out there, which is usually fireworks, some flying text, cursor chasers, sticky notes, etc.

    Since Mozilla hit 0.9 we've taken every public release and run it against our site. Initially, since we coded for IE4+ and NS4.x, Mozilla was being treated like an IE4+ browser. This was fine for the most part, but we did find a few places where we were being too IE specific (shame on us!). So we tweaked and made those pieces use more abstract HTML DOM approaches to whatever problem they were solving. Happy to say, both controls work almost flawlessly in Mozilla now also with only a little tweaking to existing code.

    Now, you might have noticed a couple of "almost"s back there. First off, the performance of in Mozilla in the DHTML area still isn't quite up to par with IE5+. I've seen the performance comparisons of other features, but none of these tests seem to tax the DHTML capabilities of the browser. We're also slowly discovering silly little things that just shouldn't exist as bugs in Mozilla. In fact, today I found one that inspired me to write this little commentary. For anyone familiar with regular expressions, try this little puppy out in NS4.x, NS6.x, IE4+, and Mozilla:

    <codeSnippet language="JavaScript">
    // A regex to trim strings
    var objTrimmingRegexp = /^s*(S+(s+S+)*)*s*$/g;

    // right answer IE4+, NS4.x, NS6.x, Mozilla1.0
    window.alert(" hello world! ".replace(objTrimmingRegexp , "\"$1""));

    //right answer IE4+, NS4.x, NS6.x
    // wrong answer Mozilla1.0
    window.alert(" ".replace(objTrimmingRegexp, "\"$1""));
    </codeSnippet>

    Also, an annoying UI bug we've seen is that whenever you have a <select size="N > 1"> list that contains enough options to cause the list to scroll, whenever you highlight an item in the list, the list control scrolls it to the top of the list.

    To wrap up, I'm truly looking forward to finally ditching support for the NS4.x in our next version of our product. Truthfully, it's not about ditching NS4.x, it's about finally being able to take full advantage of standard technologies that, while they've been around for a while, are finally supported in more than one major browser.

    Kudos to the Mozilla team for doing such a great job!

    Read more...

  • Two New .NET Articles Up On O'Reilly

    There's a couple of new articles up on The O'Reilly Network today. The first is about one of the coolest and frankly the most powerful data binding controls in ASP.NET: The Repeater. The author does a great job breaking down the different templates and how they are used. He also gives a breif example of how to add a button to the item template. IMHO, the beauty of the Repeater lies in it's ability for an data item to be represented by basically any form of content the developer chooses. An HTML table is the obvious choice, but it could be any possible text format that you need to emit.

    The second article is Sam's second on MC++. In this part, he covers the mixing of managed and unmanaged code. He covers topics such as IJW, pinning pointers and using managed code from unmanaged code. He promises a more in depth look at IJW in his next part.

    Read more...