Our second NBNUG meeting is this next Tuesday, March 18th at 7:00pm (at O’Reilly in Sebastopol of course). We were not able to get a guest speaker for this one, so Arsen and I will be presenting again. I will be presenting on the ASP.NET MVC Framework and Arsen will be demonstrating how to build a Windows Service with .NET. Here is the meeting abstract:
This meeting will have two presentations. Patrick Gannon will present on the ASP.NET MVC Framework, which is Microsoft’s forthcoming implementation of the Model View Controller pattern for developing web applications using .NET. We will construct a simple web application using the MVC Framework and Linq to Sql, and we’ll examine the differences from traditional WebForms development. Patrick will also describe how the MVC Framework better enables Test Driven Development and eases the construction of REST-based web applications. In our second presentation, Arsen Yeremin will show how to develop a Windows Service using .NET.
For a little over a month now, I’ve been learning and writing Tcl, as part of my new job at Solitex Networks. I am excited to learn Tcl because its a dynamic language, which seems to be all the rage these days. I have heard that developing web applications using Ruby on Rails is ten times faster than using static languages like Java or C#, and that part of that speed-up is due to the Ruby language (because it’s dynamic, I would assume). This post focuses on the aspects of the language that I especially like so far. I was attempting to write a full review of the language tonight, based on what I know so far, but it’s already 10:30 on a school night ;-)
The most fascinating part about Tcl is that you can re-define existing procedures at run-time. See the following example in Tcl:
proc printMyName {name} {
puts "My name is $name"
}
printMyName "Pat"
rename printMyName printName
proc printMyName {} {
puts "Who knows what my name is?!"
}
printMyName
Executing this Tcl code will print out "My name is Pat" followed by "Who knows what my name is?!". Not only can procedures (also known as "commands" in Tcl) have a different implementation depending on when you call them, but they can take a different number of arguments or even not exist at all! (I could basically delete the printMyName function by adding "rename printMyName {}" to the end of the code snippet above.) This is handy for adding cross-cutting functionality like error logging. In our code base, the "error" procedure (a built-in Tcl command that is roughly equivalent to "throw new Exception") has been renamed so that all calls to it will be logged to a rolling log file. The really nice part about it is that even system procedures (provided by Tcl or the AOLServer web app framework/server) which call "error" at run-time invoke the re-defined method containing the custom logging mechanism. This means that even if an error is not handled (via the "catch" command), it will be logged through our custom mechanism. Using this same type of approach, you can rename control structures (or you can create new ones!) This obviously allows you to customize the language much more deeply than you can in C#, for example.
Another really cool thing about Tcl is that strings enclosed in double-quotes (like the ones in the "puts" calls in the code sample above) are actually interpreted by the compiler. This means that you can put variable names in strings like "My name is $first $middle $last", or even embedded procedure calls enclosed in square brackets. I think this is much more expressive than how we would do this in C#:
Console.WriteLine(string.Format("My name is {0} {1} {2}", first, middle, last));
To print out a character with a special meaning (like '$', which is normally used to refer to a variable) you can use escape with a backslash (eg. '\$') or you can enclose the string in curly braces {like so}, which causes the compiler to not interpret the contents of the string.
My next post will focus on the aspects of the language that I am less fond of.
Arsen and I are proud to announce the first ever meeting of the North Bay .NET User Group on February 19th, hosted at O’Reilly in Sebastopol, CA. The topics of the first meeting will be ASP.NET 3.5 AJAX and the new language features in C# 3.0 (and applications of lambda expressions in Linq) - the latter topic presented by moi. We’ll be raffling off books and gettin' buck wild! I hope to see you there!
Update: Doh! It will be at 7:00 PM, and O’Reilly is at 1005 Gravenstein Highway North (in Sebastopol)
I recently read Jeff Atwood’s post entitled How Should We Teach Computer Science?, and although I can certainly relate to the sentiments expressed, my opinion differs on what the best way might be to cultivate top notch developers. I don’t think we as a community should settle for raising an army of vocational developers. I think we need to be brainstorming on how to cultivate the next Donald Knuth.
Back when I was a Computer Science undergraduate at Sonoma State, my feelings about what the coursework should be where somewhat similar to the ideas expressed in Jeff’s post. (At least as similar as they could have been considering how little experience I had working in the industry at the time.) They had me learning about Touring machines, Context Free Grammars (Theory of Computing class), functional programming (Discrete Structures class), doing RSA encryption by hand (Computer Security class) and writing assembly programs that sent and received signals. All I wanted to do at the time was learn how to make Windows programs using Visual C++, and there was no such class. That frustrated me to no end. I was constantly thinking: "When can I get out into the REAL world and start writing some REAL programs?" What I didn’t realize at the time is that writing Windows (GUI-based) applications is fundamentally about raising and handling events, which is essentially sending and receiving signals. Wax on. Wax off. Wax on. Wax off.
I think that a traditional Computer Science education, in combination with a standard regimen of general education is a fantastic bedrock for becoming a great software developer and a well-rounded human being. That said, a graduate in Computer Science (even at the finest university) isn’t necessarily a qualified commercial software developer. I think what the industry needs is a Master’s degree program in Software Engineering which is intended to transform Computer Science graduates into qualified software developers. Doesn’t it make more sense to have a program that builds on a solid foundation of Computer Science fundamentals than to try to cram yet more information into an already heavy course-load (and risk losing focus on the critical fundamental concepts). I think all of us geeks would relish in the opportunity to design a graduate program that had classes on things like source control, state-of-the-art deployment techniques (like the new VS 2008 Web Deployment Projects) and TDD. Moving these sort of vocational aspects of the education into a graduate program has the added benefit that those who are already working in the software industry but majored in something other than Computer Science during their undergraduate study have the opportunity to learn the fundamentals on their own and go directly into such a graduate program, rather than re-attain a bachelor’s degree. In general, I think we as software developers should focus ourselves on crafting our trade into a more rigorous and mature engineering pursuit, and in doing so we should try to include as many people as possible who are up to the task, in order to ensure that the brightest minds attain success and further the efficiency and capabilities of the technology that we all love and depend on. Perhaps there could even be a PhD program in advanced software engineering topics like software architecture (SOA, etc.), product management and program management. I’m all for formal educational programs which teach the skills necessary to become a competent software developer, but I definitely don’t think that teaching this pragmatic sort of material is any substitute for a solid foundation in Computer Science. That said, perhaps there is also a place for a Bachelor’s program in Software Engineering that mixes the two types of topics. The developer equivalent of a nurse practitioner might enroll in such a program, whereas the equivalent of a physician (MD) would attain an undergraduate degree in Computer Science followed by a graduate degree in Software Engineering.
Before releasing the new version of my software product, I would like to obfuscate many of the contained assemblies. The reason is that I see no point in selling a .NET application without obfuscating it. From my point of view, every .NET application should either be open source or it should be obfuscated. If one compiles a .NET application and sells the un-obfuscated binaries (without the source code), then competitors can still reverse engineer your architecture and algorithms (using de-compilers like ildasm, which is included in the .NET Framework), yet you have prevented your legitimate users from customizing your application by modifying the source code to meet their needs (de-compiling commercial code, and then maintaining changes to that code would not be worth while for most of them). I am not ready to open source this particular product (Creative Modeler) because I have put a ton of time into it over the years and I don’t think I could capitalize off that effort if I were to open source it. As such, I believe that distributing an obfuscated application is the only way to go for this product.
In the past, I have gotten Creative Modeler to work (when the application was still in .NET 1.1) after being obfuscated using Salamander .NET Obfuscator from Remotesoft, but since I’ve upgraded to .NET 2.0, I can no longer get the application to work after being obfuscated with that tool (the new version of which claims to support .NET 2.0). It proclaims success during obfuscation, but then I get the nasty error message below when I try to run the obfuscated app, and then it exits. I emailed Remotesoft support and got no response.
Method 'E' in type 'A.b' from assembly 'SDA.Diagrams, Version=1.0.2880.42229, Culture=neutral, PublicKeyToken=null' does not have an implementation.
If you’re going to charge 800 bucks for an obfuscator, it should work out of the box (IMO), or if it doesn’t, you darn well better at least answer my email. (I haven’t bought it, and I sure won’t if I can’t get it to work.) The only serious competition seems to be good-old Dotfuscator from PreEmptive Solutions. I’ve had problems with that one in the past, and it’s even more expensive than Remotesoft! Although there are other .NET obfuscators out there, they all seem to be either over-priced or lacking critical features (or both). Desaware released a .NET obfuscator under the MPL, but oddly enough, they make you agree that you’ve purchased their $40 book about how to write an obfuscator before they will let you download the source code. To me, that seems like it is a bit of a contradiction. They’re basically saying: Our software is open source, but only if you pay us. Whether or not that is actually legally enforceable (couldn’t one person just buy the book and then provide a location where everyone can download the source?), it certainly doesn’t seem like a good way to foster an open source project.
One of my favorite things about being a software developer is that if I discover that there’s an application or tool out there that’s needed, and it doesn’t exist, I can just make it if I want to. I am interested in creating an open source .NET obfuscator, but I am wondering if this would be perceived as a contradiction. I personally think there could be a sizable need out there for an open source .NET obfuscator, because I think even on the Microsoft stack: commercial software has it’s place and open source software has it’s place (which includes utilities like obfuscators!) Let me know if you think there would be much of a need for this, and/or if you think it’s a contradiction.
I drove down to Mountain View last night for the Visual Studio 2008 Installfest, and it was a blast! The presentations were interesting, the food was good and I couldn’t help but marvel at the vast brain power in that room. (There had to be over 200 .NET developers in that huge ballroom on the Microsoft campus in Mountain View - it was standing room only.) I met a ton of really interesting people including Anand Iyer (Microsoft Developer Evangelist), Oliver Nguyen (President of the Bay .NET user group) and Scott Stanfield (CEO of Vertigo). Anand introduced me to Arsen Yeremin, who has also been looking into starting a .NET User Group in the North Bay. Arsen seems like a really smart guy, and I’m excited to have a partner in crime to help get the user group started. I also heard rumors that Parker CompuMotor (a former employer of mine from nearly a decade ago) is using .NET these days, so I’m brainstorming about how to reach out to those folks (I’m not sure if anyone I worked with still works there) to see if anyone there is interested in the user group. I also talked to Marsee Henon at O’Reilly this week, who gave us tentative approval to use their headquarters in Sebastopol to host the meetings.
I am trying to start a user group for .NET developers in the north bay and north coast. (I live in Santa Rosa, CA.) I did a search on myspace (for developers near Santa Rosa) and sent out some messages to a handful of local strangers who were very friendly, but I only found a couple of people interested in a .NET User Group. If you have any ideas for how I could get the word out to people that might be interested (or if you’ve seen any good resources on the web about starting user groups), please post a comment. I have contacted Oliver Nguyen, the President of the Bay .NET User Group and it seems like there is a possibility that I might be able to organize this as the North Bay chapter of that User Group (after all there is already an East Bay chapter and a South Bay chapter). That would enable me to use their non-profit status, which would make things a lot easier. The East Bay chapter is having an event entitled Architecture for 2008 and Beyond this Wednesday in Pleasanton, and I’m thinking about going, but it would be over an hour and fifteen minute drive for me (which is why I’m looking into starting a North Bay chapter ;-) )
Entity Framework (the new Microsoft OR/M) Beta 3 and Entity Designer CTP2 (which both work with Visual Studio 2008 RTM) were released today. To download them, go to the following URLs:
Entity Framework: http://www.microsoft.com/downloads/details.aspx?FamilyId=15DB9989-1621-444D-9B18-D1A04A21B519&displaylang=en
Entity Designer: http://www.microsoft.com/downloads/details.aspx?FamilyId=D8AE4404-8E05-41FC-94C8-C73D9E238F82&displaylang=en
For more information on the improvements since the last version, see these posts from the ADO.NET team blog:
Entity Framework: http://blogs.msdn.com/adonet/archive/2007/12/05/ado-net-entity-framework-beta-3-rleased.aspx
Entity Designer: http://blogs.msdn.com/adonet/archive/2007/12/05/entity-framework-beta-3-breaking-changes.aspx
We're working on a commercial website that will leverage the Entity Framework. More on that soon...
Updated: If you haven’t checked out the Entity Framework yet, go read Julie Lerman's article: Introducing ADO.NET Entity Framework.
I recently read an article called Windows Workflow Foundation Essentials by Kevin McNeish in CoDe Magazine. In the article, Kevin shows how you can create a WF application using a Visual Studio template (and you get a nice GUI for editing workflows) and you can easily add activities that call a managed code block (the "Code" activity) or a web service (or a host of other things). You can also develop a custom activity which is functionally equivalent to adding a built-in "Code" activity, but it is a re-usable component that can be plugged into other workflows (whereas a "Code" activity is tied to a single wofklow). To do that, you override the "Execute" method in your new custom activity (which inherits from the Activity base class, or alternately the SequenceActivity class if the custom activity should contain child activities) and that method is called by the WF when the activity is run. All makes sense so far. The rub (IMO) comes in when you want your custom activity to accept a paremeter or return a value that another activity can use. (In the example, the custom activity "ValidateCustomerActivity" returns a boolean that is wired into an "IfElse" built-in conditional activity.) Nearly all custom activities would require at least one "dependency property" (a parameter or a return value). Jim demonstrates a Visual Studio code snippet that comes with WF that is kicked off when you type "wpd" inside a class definition, that is used for generating a dependency property. IMO, the fact that you need a code snippet to declare a return value should have clued in the architect of the WF that maybe they should re-consider their approach. The code snippet invokes a dialog which generates the following code for the return value of the custom activity from the article:
public static DependencyProperty CanCustomerOrderProperty = System.Workflow.ComponentModel.DependencyProperty.Register("CanCustomerOrder", typeof(Boolean), typeof (ValidateCustomerActivity));
[Category("Custom Property")]
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public Boolean CanCustomerOrder
{
get
{
return ((Boolean)(base.GetValue(ValidateCustomerActivity.CanCustomerOrderProperty)));
}
set
{
base.SetValue(ValidateCustomerActivity.CanCustomerOrderProperty, value);
}
}
Yuck! In the trivial custom activity shown in the article, there are three custom dependencies: one for the return type (above), one for an input parameter (which is bound to a parameter that is passed into the workflow itself - customer ID) and a business object that the activity invokes. Multiply the above code by three and you have a lot more boilerplate code than descriptive functionality in your custom activity class. IMO, this would have been so much nicer if the WF team had leveraged a real Dependency Injection tool like Castle Windsor, instead of rolling their own hokey "activity data binding" (which results in the ugly code above). There has got to be a way they could have implemented this with a real DI tool such that the syntax could have much more terse, like the following:
[CustomProperty]
public Boolean CanCustomerOrder { get; set; }
Had they done it this way, they wouldn’t have needed the code snippet and we would have much more readable code in our custom activities. To add insult to injury, the "activity data binding" implementation means that we would also need to fire up an actual workflow in the WF in order to unit test our custom activity. Of course one could write their custom activities to delegate all the heavy lifting to business objects that can be unit tested, but this type of approach seems to invite un-testable code (as in traditional N-tier ASP.NET applications where business logic has a tendency to creep into event handlers in ASPX code-behinds over time).
Aside: To get syntax-highlighted code into Windows Live Writer, I had to write it in Visual Studio, paste it into Word, save it as HTML, edit the HTML file in notepad and paste the raw HTML into the HTML view of WLW. Is there an easier way?
I read on the Bay .NET User Group website that the Visual Studio 2008 Installfest for the bay area will indeed be in Mountain View on December 13th. I had read on Scott Hanselman’s blog that it would be on that date in Mountain View, but the link from his post initially went to information about the Denver installfest. The following is the announcement from the Bay .NET site:
Visual Studio 2008 Install-Fest and .NET Holiday Party
Thu, 12/13, 6:30 PM, Microsoft Silicon Valley Campus - 1065 La Avenida Street - Mountain View, CA 94043
Visual Studio 2008 has been released to manufacturing! Join Microsoft and all the Northern California .NET User Groups for a Visual Studio 2008 Install-Fest and Holiday Party on December 13th, 2007! Visual Studio 2008 is HERE and this event is your opportunity to get your hands on the released version before anyone else!
Click here for event details and to register...
I had been hoping to make it, but this page says it’s already full.