CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Glenn Block

February 2008 - Posts

  • Web Client Software Factory 2.0 shipped!

    As promised, WE'RE LIVE!!!!!

    image 

    (Image courtesy of hyku via http://www.flickr.com/photos/hyku/480867085/)

    After a long haul and several posts such as here and here, we're finally out the door with the next version of the Web Client Software Factory!

    Read more about the release from Blaine and Mike!

    Highlights include

    • Runs on Visual Studio 2008 and .NET 3.5
    • New stand alone Guidance Assets that you can pull into your existing sites without the entire factory. (Currently only for Visual Studio 2005, but will be revved for Visual Studio 2008)
    • Adds support for ASP.NET AJAX and new AJAX extenders
    • A boat load of new Quickstarts and How-Tos
    • New Order Management Reference Implementation
    • Significant perf enhancements

    WCSF 2.0 has something for ASP.NET developers everywhere. We've done a bunch of work adding new capabilities that you can pull into your existing ASP.NET sites without needing the entire factory. This means if you don't want to commit to using the entire factory in your apps, you don't have to!

    Thanks foremost to my team, and all the partners, advisors and customers who helped make this a reality.

    Download the bits from the landing page here.

    GO!

  • XML and Fluent Interfaces

    I have posted several times in the past on Fluent Interfaces. I think about Fluent Interfaces much in the same way I think about recursive functions, that is they are not for everything, but when you find the situation that warrants them then they are a great fit. On the other hand when you try to use them for the wrong situations they are an awful fit.

    In the past, I've found at various orgs that i am constantly creating an XmlUtils() class to handle the creation of documents in a more tighter syntax. Back in those days, I was unaware of Fluent Interfaces and how they could possibly tackle this problem

    Well today I just came across Mark Resmussen's sweet FI for defining an XmlDocument, and it looks like a great fit.

    XML we are trying to create

    <?xml version="1.0" encoding="utf-8"?>
    <root>
        <result type="boolean">true</result>
    </root>

    Using System.Xml

    XmlDocument xd = new XmlDocument();
    xd.AppendChild(xd.CreateXmlDeclaration("1.0", "utf-8", ""));
    
    XmlNode root = xd.CreateElement("root");
    xd.AppendChild(root);
    
    XmlNode result = xd.CreateElement("result");
    result.InnerText = "true";
    
    XmlAttribute type = xd.CreateAttribute("type");
    type.Value = "boolean";
    
    result.Attributes.Append(type);
    root.AppendChild(result);

    New way using Mark's FI

    XmlOutput xo = new XmlOutput()
        .XmlDeclaration()
        .Node("root").Within()
            .Node("result").Attribute("type", "boolean").InnerText("true");

    ANY QUESTIONS?

  • Web Client 2.0, what's the hold up?

    1125019024_78380c1372[1]

    As is obvious from the comments, we've hit some delays. This reason is due to GAT/GAX issues with version 1.4. Those issues have been resolved and GAT/GAX 1.4 has now shipped. I guess you can say that the previews ended, but then the film broke while we were setting up the projector :) I am happy to say we are back on track now and planning to ship next week. Thanks for your patience.

  • Patterns, it's about teaching people how to fish

    351022855_ebbb37749d_b[1]

    Today Larry Brader (Our Lead Test Manager) and I were having an interesting conversation that led me to make the above statement. Larry and I were discussing the root drivers for many of the architectural qualities I have been pushing on within the "Prism" project. This includes qualities such as Simplicity, Subsetability (no I did not make this word up) and Compatibility. As I began to explain, I quickly started working back historically, until I ended up right back at Jeremy's "Build your own CAB" series and the great "CAB" bash that ensued from his initial talk at DevTeach.

    The crux of Jeremy's argument was that if it's a choice between learning patterns or learning to use a tool that implements those patterns (CAB) then he would choose to learn the patterns. It may surprise you, but I agree completely (though not everyone agrees). The second part is that if you are going to use a tool, then knowing the underlying patterns behind the tool means you are more effective in the use of that tool and also gives cross transferable knowledge that you can use either in the absence of a tool, or apply to a different tool.

    In Software Development we know that the one thing that is constant is change. Some things may stay the same, but as we make new discoveries at the hardware, software language, and methodology level, change occurs. Just about 60 years ago software development was limited to an elite few who developed software inscribed on Hollerith cards. The tools you use today will not be the tools you use tomorrow. Take languages for example. My first exposure to computing was Basic on a Commodore Vic-20. Since then I have learned several variations of Basic (at least 5 I can think of), Logo, Fortran, Pascal, A few flavors of Assembler, C, C++, Javascript, PHP, Java, C#, and now Ruby.

    What's common about all these languages? It's the behavior those languages encapsulate which can be expressed in pseudo code. Quite simply (and this is an oversimplification), it's Input, Process and Output. This I would argue is another constant that won't change. At the end of the day every programming language needs to support this. As I said this is an oversimplification in that there's a ton of sub-behaviors that you could put under each of the three. However, even at that level you will can find a common set that pervades all languages. In essence these are patterns of languages. Once I understand these patterns that means I can learn any language. The semantics (implementation) of the language continually changes, but the patterns stay the same

    It's the same with software design patterns. Take the Factory pattern for example. At an implementation level the Factories of today are very different than the factories that were created back when the gang-of-four first coined them, however they still are factories. If twenty years ago all I learned was how to use the OldLanguageFactory then that doesn't necessarily help me use the NewLanguageFactory of today. I may not have even understood that the OldLanguageFactory is in fact a factory. However if I understand the factory pattern, then I can use that transferable knowledge to use the NewLanguageFactory. I'm also able to build a NewLanguageFactory if one doesn't exist. The same argument can be applied when looking at the CAB. CAB at it's essence is an implementation of a set of patterns including Dependency Injection, Builder, Composite, Command, PubSub, etc. If you understand the underlying patterns then you have transferable knowledge that will have benefits that transcend the current tools.

    In the Web Client Software Factory, it is this rationale that drove the MVP Bundle. Since I joined p&p, I heard countless feedback from customers who did not understand how to properly implement MVP. Having the automated recipes that generated the presenter, view, and view interface and wired everything together was not enough. It's like great you did that for me, but now what do I do? So in the MVP bundle, we decided to focus on the pattern itself and then show you how you can implement MVP yourself without having an dependencies on the CWAB (Composite Web Application Block). We then showed you additionally how using the CWAB aids you in implementing MVP. Having that understanding of MVP means you can take that knowledge and implement it yourself, look at other alternatives besides CWAB that might aid you or use CWAB. It's really up to you.

    Back to the fishing metaphor. Think of the patterns as you would think of knowing how to fish. Then think of CAB, CWAB, Prism is different kinds of fishing poles. Think of the challenges you are addressing in your apps as the fish. If all you learn is how to use one fishing pole, then that's not very useful. Having a knowledge of fishing means you are free to choose the pole of your choice, or create your own ;-)

    In the new "Prism" work you are going to see us driving seriously on the underlying patterns for building Composite WPF applications rather than just reusable code libraries. Yes we'll give you a fishing pole (though it may not be the right pole for catching every kind of fish) but we'll show you how to fish first.

  • Have you heard of SFD?

    OK, you've heard of TDD and BDD, but have you heard of SFD? SFD stands for Simple-First Development. It's a principle that we're driving on as we move forward in our "Prism" (Composite WPF) project. Essentially it means that when we attempt to solve any problem, let's start with focusing on the easiest path that addresses the most common cases rather than over-complexifying the simple cases in order to handle the edge cases.

    Let me give you an example to show you how we are applying this principle. One of the features that CAB provided was allowing you to have modules that dynamically populate content anywhere on the screen by grabbing a handle to a Workspace that lies somewhere in the cloud by using it's key name. The mechanism is so flexible that it allows Module A to load a new Workspace into an existing workspace in the Shell, and then Module B can come along and dynamically add content to that Workspace from Module A.

    So what's the problem with this? Well the problem is it introduces complexity, reduces debug ability, learn ability and in some cases may even post a security issue. It introduces complexity because suddenly I have things magically appearing throughout my app, that I may have to spend quite a lot of time tracking down. Depending on the complexity of this system, this could be an arduous task. Learn ability is affected because now in addition to understanding the tangible pieces of the system that i see, I have to be concerned about a whole other magical world that i don't see. The security issue maybe that I may not want certain modules to be able to populate their content into a specific portion of the screen, but because everything is dynamic, I have no way of really controlling it. Even if I could do it, it would be very ugly.

    As we've been working on "Prism" we've encountered this same problem, and although our first instinct was to use a similar pattern, we took another look with the Simple-First approach in mind. In "Prism" we have a notion of Regions which are similar to workspaces. A Region is a place to store content (views). At the shell level we decided that we should allow modules to push views into named regions in the shell. This makes sense because in a composite application you may have many teams that are all contributing content to the shell. You don't want the shell to become a hotspot with every team having to modify it to hard-code where the injection of screens.

    For example, imagine an ERP system where there are many different sub-systems that are accessed from a navigation tree on the left side of the screen. Each sub-system is potentially maintained by a different team.As you click on the sub-system, it loads up the screens for that  right portion of the screen.

    Now let's say that sub-system say Purchasing is actually deployed among several modules. So one module (PurchasingModule) loads up that has the main set of screens which are added to the shell. Then additional modules may load for the sub-system such as PurchasingHistoryModule. PurchasingHistoryModule then has some views like HistoryView that it wants display in PurchasingModule. But there are other modules as well that might contribute content to PurchasingModule like the PurchasingTrackingModule. But, PurchasingModule doesn't have any direct references to those other modules.

    Below is a diagram to illustrate this.

    image

    So how do we apply Simple-First to solve this problem without doing the module push. Instead we do an explicit pull model. But wait, PurchasingModule doesn't have any direct references to the other modules right?. Aaah yes, so instead create an interface assembly that has interfaces for all the different views that PurchasingModule shares. Then each "child" module that loads can register it's views when it loads with the IOC. The PurchasingModule's Presenter however can contain explicit code that pulls the views from the container that it needs, and it can populate them as it sees fit.

    For example see the code below (just for illustration)

    class PurchasingPresenter {
       ...
       public void OnLoad() {
          IHistoryView HistoryView = container.Get<IHistoryView>();
          Put(HistoryView).In("HistoryRegion");
       }
    }

    Will this approach handle all cases? probably not. But we think it will address a large set, and for those cases will make the code more maintainable and easier to debug. Applying simple-first, we'll stick with it for now. Once we see a need we'll consider applying complex-next. ;)

More Posts

This Blog

Syndication

News

View Glenn Block's profile on LinkedIn

Me