Latest Posts
I use the Windows XP Virtual CDRom Control Panel regularly. It's a great utility for mounting .iso files to a virtual cd rom drive to avoid having to burn them to an actual disk. Many large development tools (especially from MSDN) are distributed in .iso format for download. However, one of the most frustrating errors with the tool is the ambiguous "Mount Failed" exception that is sometimes thrown.
I received that error this morning while trying to mount the Visual Studio 2008 Pro image. I remembered running into this exception on numerous other occasions but couldn't remember the exact cause. After a small amount of googling and experimentation I found that my problem was caused by whitespace in the file path to the .iso I was attempting to mount.
Removing the whitespace from the file path (I just copied the .iso to the root of my C:\ drive) fixed the problem, so this time I decided to blog it in case I run into the problem again in the future.
To implement a print button on a web page, you can use the window.print() javascript function. The following example shows an image that is displaying a printer icon and will print the current page when clicked.
Code:
<img border="0" onclick="window.print();" src="/images/PrintIcon.gif" style="cursor:hand;" />
(Replace the text /images/PrintIcon.gif with the location of an icon in your site.)
Example:
A better application of this idea is to first create a page that renders a print preview of the information you want to print. This print preview will look similar to the original page but will not contain navigation items, header images, or other page clutter. Furthermore, the data can be formatted to fit cleanly on 8.5" x 11" paper. Embed the print icon in the print preview page and allow users to print from there.
I came across an issue today that I think perfectly exhibits the principal of forward thinking in coding. Consider the following block of code:
IList<MyObject> myList = myAdapter.Read();
if (myList.Count != 0)
{
... do some work ...
}
The if statement is only executing its contents if the count of objects in the list is not zero. This seems pretty harmless on the surface. We're taking an IList<T> after all and we know that List<T>.Count returns zero if the list is empty. Therein lies the trap. We're not necessarily talking about List<T> here, we're talking about any class that implements the IList<T> interface. You can see the facepalm coming a mile away.
What if a class implements IList<T> and decides to return -1 for .Count to represent an empty collection. This is actually more common than you'd think as there seem to be a large number of people out there who still use -1 as a return code for anything that is empty or not initialized. The solution here would be to instead check for:
if (myList.Count > 0)
Instead of checking for Count != 0, we instead check if Count is greater than zero. It doesn't matter now whether the IList<T> implementation returns 0, -1, or -999 for Count to indicate an empty collection, the assertion that the if block should only run on a non-empty list still stands.
As we all know, I'm a little slow on the uptake. This time I managed to miss a really great keyword in C#: yield. The combination yield return is a lovely piece of C# candy that can be used to simplify a common function. Consider the following section of code:
private IEnumerable<MyObject> FindObjectsWithThreeChildren(IEnumerable<MyObject> sourceList)
{
IList<MyObject> results = new List<MyObject>();
foreach (MyObject obj in sourceList)
{
if (obj.Children.Count == 3)
results.Add(obj);
}
return results;
}
We've all written something along those lines before. Build a collection up based upon some predicate and then return it. Now yes, this could actually be solved much more cleanly using a lambda expression with LINQ, but it could also be simplified using yield return. The following is the same method written to take advantage of this new keyword:
private IEnumerable<MyObject> FindObjectsWithThreeChildren(IEnumerable<MyObject> sourceList)
{
IList<MyObject> results = new List<MyObject>();
foreach (MyObject obj in sourceList)
{
if (obj.Children.Count == 3)
results.Add(obj);
yield return obj;
}
return results;
}
The difference between yield return and a regular return is that with the yield keyword the method does not exit. Instead the returned result is simply added into the collection to be returned.
For obvious reasons, this can only be used for methods that return enumerations. It doesn't do anything spectacular but it does make the source code a little bit cleaner and clearer, which can only be a good thing!
I've been using TFS for a little over six months now and despite having its good sides, it also rears several quite ugly ones. I'm not going to harp on the obvious feature deficiencies such as branch and merge because we all know they aren't in there and that comes down to a technology choice. No, the things that really get under my skin about TFS are things that should be basic to any piece of software.
1) Check In, Lose Comments
* This is an extremely frustrating flaw in TFS for me. If you check in, but a later version of the project or file you're working on exists on the server (common in larger teams) then the project must be reloaded. After the project is reloaded, selecting CheckIn displays the exact same dialog you were in thirty seconds ago sans comments. Urrggghhh! I now always copy my comments to a clipboard or write them in textpad prior to nervously clicking the CheckIn button.
2) Updating list of changesets and work items - Please wait while we waste your time
* Does anyone else remember when a build took less than ten seconds to complete? I know that I do. If I press Ctrl+Shift+B in Visual Studio, the entire solution is built in about three seconds. If I right-click the solution and select Run Test(s) then all of the unit tests run in about thirty seconds. Why then, please educate me dear reader, does it take a full three minutes for a TFS build to do the same things!?!? Sigh.
3) Working Offline - I just need to edit this one file .... rrgghhh ... come one ... rrggh ... oh screw it!
* Perhaps in happy TFS land there is a place where internet connections are never lost and even the clouds come fitted with wireless network bridges. However, that is a far cry from where I live and work. We've all been there. You're offline, you need to make one small change and...nope...you've been sent to TFS connection jail. Enjoy your stay!
Back in the before times, it wasn't such an uncommon thing to hack up an html INPUT to include "extra" attributes like 'errorMsg="Enter a number between 1 and 12" minVal="1" maxVal="12"' to aid in the client side validation of an input. Of course in the modern day web, this practice is well, let's just say undesirable. The most common alternative is to create a bunch of dynamically generated "onblur" and separate on "onsubmit" function calls.
Things like 'onblur="checkRange(this, 1, 52, 'Enter a valid Week Number');"', combined with "validateSubmit( … code … if(!checkRangeS($get('MyWeekTextBox'),1,15,' Enter a valid Week Number')){ return false; } …more code …);". The basic issue with this approach is there tends to be some duplicated code. On the other hand things like the errorText can be pushed into a "hash" table and accessed as a resource. There are other things that can be done to make this a cleaner approach, but to me they all fall short of using the object like structures of JavaScript.
What if you create a validation object, attach it to a property on the input, then wire some event handlers, you can define something from any point in the page's client lifecycle that has that write-once, use and re-use goodness of object oriented development. There are several considerations with this approach, the first of which is that depending on your approach you can introduce a fair amount of runtime JavaScript bloat. On the other hand if you really take some time to understand what you're getting into you can create a clean, reusable lightweight validation framework.
Before I go any farther, let me state in the most direct of language, that Client Side validation is only a usability enhancement for a web application, It has absolutely nothing to do with insuring valid data for processing. It cannot ever be trusted as a reasonable source of validation for any serious data capture system. Sure you can get pretty clever with your client side checks, but remember especially with some of the client JavaScript debugging tools out there, anything you do can be bypassed. So why even do it? Well the vast majority of users will benefit from the aid that rapid client side intervention on erroneous data entry provides. Range, type or required field validations are very helpful to your average user.
Okay enough tongue wagging. Let's take a look at some functions:
The numeric validator – In this function we are both, storing the min, max, required, and error message as well as providing a method to initiate the validation. One note, the Validate function takes an obj parameter, and truthfully this is not really necessary, because this validator will be assigned to an input, it can carry a reference to the input it is validating and do away with that parameter. I'm not a fan of that, I liken to say a Domain with Person and Car. A Person may have 1-n Cars, and a Person may Sell a Car, but a Car cannot sell itself from a Person. Even though the data defines the relationship as 2 way, there is a clear owner and owned that define who in Code should really know about the other. In effect Person may have a Collection of Cars, but a Car might only have a PersonID, a pointer, but not a reference to its owner. When I thought about this object based validation this seems like a good approach.
function numVdtrSet(req, min, max, msg){
this.Req = req;
this.Min = min;
this.Max = max;
this.Msg = msg;
this.Error_handler = null;
this.Value = null;
this.Validate = function(obj){
this.Value = obj.value;
if (!validateNumberField(this)){
obj.error = true;
return false;
}
obj.error = false;
return true;
}
}
The validator creation and assignment – Here we're creating the validator, and if an event is provided wiring it up. In our case the we will be passing in an iEvt of onblur for the textbox, and an evt of focus to pull the cursor back. Critical to this is tracking the error state of the input, if we've flagged it as bad, let's not keep pulling them back in an endless loop. We have a submit check, and remember this is only meant to be helpful, not strict enforcement.
function setHandler(obj, iEvt, req, min, max, msg, evt){
obj.error = false;
obj.validator = new numVdtrSet(req, min, max, msg);
obj.validator.Error_handler = function(s){
alert("Error: " + s + "\r\n" + this.Msg);
if(evt && !obj.error){
obj[evt]();
}
}
$addHandler(obj, iEvt, doValidation);
}
The validator – nothing special here, it's not the best validation check, but this is part that should be most familiar if you've ever done client side validation.
function validateNumberField(vldtr){
var _iVal = null;
if (vldtr.Req || vldtr.Value != null){
try {
_iVal = parseInt(vldtr.Value)
if (isNaN(_iVal)){
processError("type", vldtr);
return false;
}
} catch(e){
processError("type", vldtr);
return false;
}
if (vldtr.Min && (vldtr.Min > _iVal)){
processError("minimum", vldtr);
return false;
}
if (vldtr.Max && (vldtr.Max < _iVal)){
processError("maximum", vldtr);
return false;
}
}
return true;
}
The error handler – if ones provided call out to it.
function processError(errType, vldtr){
if (vldtr.Error_handler){
vldtr.Error_handler(errType);
}
}
The triggers – what fires these validations.
function doValidation(){
if (this.validator){
this.validator.Validate(this);
}
}
function onSubmit(){
var inps = document.forms[0].getElementsByTagName("input");
for(var i=0;i<inps.length;i++){
if (inps[i].validator){
if (!inps[i].validator.Validate(inps[i])){
return false;
}
}
}
return true;
}
The markup – actual usage
Enter a score between 50 and 3000:<input type="text" id="score" name="box" /><br />
Enter a number between 5 and 15:<input type="text" id="num" name="box" /><br />
<asp:Button ID="FakeSubmit" runat="server" Text="FakeSubmit" OnClientClick="return onSubmit();" />
<script type="text/javascript">
function setValidations(){
setHandler(document.getElementById('score'), 'blur', true, 50, 3000, 'Enter a valid score between 50 and 3000', 'focus');
setHandler(document.getElementById('num'), 'blur', true, 5, 15, 'Enter a valid number between 5 and 15', 'focus');
}
window.onload=setValidations;
</script>
I mentioned using this pattern in front of a WebMethod. That's still my intent, but this ended up being a lot to post, so we'll have to cover that in a subsequent post. This isn't a fully polished validator, rather just a pattern for perusal. I like the idea of working a more formal typed/oop process, even if JavaScript doesn't really enforce it.
Quick note, I'm still plugging away at prepping my .sdf file for my domain series, but it's slow going. I should be back into that series by Monday 11/5, but in the mean time, more on this.
Here are there functions that are using the checkthis function we defined here as well as using this to reference some data. The results of the alert portion of these functions almost always gives me pause, and if it's been a few weeks since I last thought in JS, I probably would get them wrong. There are some parts that are not to odd, but 2 points usually catch me.
- In xBthis this.myvar refers to the externally declared myvar. This is somewhat intuitive, it's just troubling, and potentially a gotcha, that you can have both myvars exist without conflicting, or overwriting values.
- The non this –ed myvar in the x function, refers to the externally declared myvar as well. Again, it sort of makes sense, as I haven't explicitly scoped it, but it's just plain odd.
var myvar = '0023';
function xAthis(){
var x = this.myvar;
alert('x is: ' + x + ', myvar is: ' + myvar);
checkthis(this);
}
function xBthis(){
var myvar = '234';
var x = this.myvar;
alert('x is: ' + x + ', myvar is: ' + myvar);
checkthis(this);
}
function xCthis()
{
var fn = function(){};
fn.myvar = 'AADS';
fn.foo = function(){ var x = this.myvar; alert('x is: ' + x + ', myvar is: ' + myvar); checkthis(this); };
fn.foo();
}
The output from these calls are as follows (not including the checkthis output):
xAthis-- x is: 0023, myvar: 0023
xBthis-- x is: 0023, myvar: 234
xCthis-- x is: AADS, myvar: 0023
So what, right? Well, there are some times, when you can use the this your advantage. Consider this line from yesterday's script. This is a pretty common usage of this, the OnClick even of a button very often passes a this into a function to avoid storing variable references all over the place:
dv.ondblclick = new Function( "document.documentElement.removeChild(this);disposeObj(this);" );
In fact you can get creative, or really you can just start to treat JS much more like C#. Say you have a bunch of elements you need to "style" when a button is clicked, first you define a container to hold a the style definition
function styleObj(className, visible, top, left, zIndex){
this.ClassName == className;
this.Visible = visible;
this.Top = top;
this.Left = left;
this.Zindex = zIndex;
}
Create factory:
function styleFactory(obj){
if (obj.checkState){
return new styleObj("Foo", true, "10px", "50px", 1000);
}
else{
new styleObj("Foo", true, "80px", "50px", 1000);
}
}
Then you can write something like this:
<input type="checkbox" id="cbx" value="01"/>
<input type="button" id="cbxbtn" onclick="doStyle(styleFactory(this));" />
And run this script on load:
function init(){
for(var inp in document.getElementsByTagName("input")){
if (inp.type == "checkbox"){
document.getElementById(inp.id + "btn").checkState = inp;
}
}
}
Not particularly useful, but the idea is that you can use references, and objects just like you would in C#, it saves lookups, extra variables and other nonsense. Next time, I'm going to use this type of relationship chaining to show a way to manage some client side validation to support a WebMethod based UI…
There are many churlish titles that I could use for this post, but for now I'll moderate my juvenile sense of humor. Today I'm just going to show a simple JavaScript function that pokes around a 'this' to see what it smells like. First off I'm not really planning to go to the level of the ECMA Script specs, nor really am I planning a thorough explanation of the object-like structures of JavaScript functions. I'm going to cover the basics of understanding context, and how to use it, and how it can cause headaches at some point. For a more detailed explanation, check out K Scott Allen's blog he's got some really good posts on JavaScript scoping.
What I'm interested is in talking briefly about why in yesterday's post I wrote the following:
extender = Sys.Application.findComponent(extenderID);
extender._lyt = extender._layout;
extender._layout = function layoutExtension(){
alert('a');
if (_doLayout && this._lyt)
{
alert('g');
_doLayout = false;
this._lyt();
}
};
The red section is what I'm focusing on, why and what does the "this" mean here, and why don't I just write something like:
function doLayout(){
alert('a');
if (_doLayout && this._lyt)
{
alert('g');
_doLayout = false;
_lyt();
}
};
var _lyt = null;
function() ….{
extender = Sys.Application.findComponent(extenderID);
lyt = extender._layout;
extender._layout = doLayout;
The real answer lies in the extenders' function _layout():
_layout : function() {
/// <summary>
/// Position the modal dialog
/// </summary>
…
var xCoord = 0;
var yCoord = 0;
if(this._xCoordinate < 0) {
var foregroundelementwidth = this._foregroundElement.offsetWidth? this._foregroundElement.offsetWidth: this._foregroundElement.scrollWidth;
Notice the reference to the this object. If I were to set extender._layout equal to a function defined in the scope of the page, when I delegate down to the _layout function, the this object wouldn't have a foregroundElement to interrogate. However when I essentially extend the original like this, extender._lyt = extender._layout the this object refers to the extender itself. Unlike the friendly world of C# where this always refers the object that contains the actual code, this in this case is much more akin to something generated using the Reflection.Emit or code generation functionality. It's all about the context of execution. Because JavaScript is such a fuzzy language, it's easy to get tripped up on where variables and functions are scoped. I've tripped myself up more than once by using the same var name in both a global and local context, or worse still by re-declaring a function or variable. Unfortunately I don't have any great tips for avoiding pitfalls like that, other than when you put a page together from multiple controls that each might have their own JavaScript, take the time to open up Fiddler or some other JS Debugger and look at what's on the page.
Being that I'm somewhat of a trial-and-error based web developer, when I was tinkering around with the code above, actual did forget to take execution context into account. Basically I use the rule that a this in the scope of a function, always refers to the containing object, if it's the page, the containing object is the document, if it's a property or prototype on function, its containing object is its parent function. This translates something like this; if you see some code x.foobar = this.myvar; this refers not to x but to x 's containing object; whereas x.foofoo = function(){ alert(this.toString());} this refers to x. This is because the this is being referenced inside (in the scope or execution context of) something that is defined as a method/property/extension/prototype of x.
Okay so the last thing I want to toss in is a simple function I use sometimes to figure out what this I'm really working with. In reality any JS object can be tossed at it, and it will pour out its contents. Although this function dumps its output to a <div/> it's pretty easy to extend it to dump its output to an Xml string, and then in turn push that into a grid, with links that allow drilldowns, and pretty soon you have a very simple JS Watch window, but I'm the type who likes quick and dirty, so here it is. Basically it just pokes an object to see what's been hung on it, and dumps the output to a div. It's somewhat tweaked to poke AjaxToolkit objects whit the extra get_ checks, but that can be pulled or other customizations like checking specific HTML Properties/Attributes could be added, hope this is useful to someone.
USAGE
… code …
checkthis(this);
… more code …
function checkthis(obj, useAlertBit){
if(!obj){
throw 'Cannot evalutate null';
}
var crlf = (useAlertBit) ? '\r\n' : '<br />';
var error = '';
var output = 'obj - Properties' + crlf
+ getVal(obj, 'id') + crlf
+ getVal(obj, '_id') + crlf
+ 'Type: ' + typeof(obj) + crlf+ crlf;
for(var i in obj){
try {
output += i + ': ' + obj[i] + crlf;
if (i.indexOf('get_') != -1 && obj[i]){
output += i +'-Value: ' + obj[i]() + crlf + crlf;
}
else{
output += crlf;
}
} catch (e) {
//alert(e.message);
error += 'Error: ' + i + ' - ' + e.message + '\r\n';
}
}
if (error != ''){
alert(error);
}
if (useAlertBit){
alert(output);
}
else {
var dv = document.createElement('div');
document.documentElement.appendChild(dv);
dv.style.width = '1024px';
dv.style.height = '800px';
dv.style.overflow = 'auto';
dv.style.position = 'absolute';
dv.style.visibility = 'visible';
dv.style.display = '';
dv.style.backgroundColor = '#ffffcc;';
dv.style.border = 'solid 1px #0000cc';
dv.style.top = '50px';
dv.style.left = '5px';
dv.style.zIndex = '100';
dv.title = 'Double Click to close';
dv.ondblclick = new Function( "document.documentElement.removeChild(this);disposeObj(this);" );
dv.innerHTML = '<pre>' + output + '</pre>';
}
}
function getVal(obj, key){
if (obj[key] != 'undefined'){
return key +': ' + obj[key];
}
return key +': N/A';
};
function disposeObj(obj){
obj = null;
}
I'm taking a few posts off from my Domain in the Box series mostly because I'm taking the time to move my data from a bunch of static methods in code to a nice neat like Sql Data File (.sdf) in VS 2008 Beta 2 (did I mention that I'm sold, really sold on Beta 2). That's going to be a tedious process that will take a few days, so when I'm done I'm going to pick that series up once I'm a little farther along with the move. In the interim I'm going to address a few short topics around poking the AjaxToolKit with stick.
Today's topic? The Sys.Application.findComponent function. Components. I've used it before here, but I've not really covered why you might use it. Basically I've used it for the task of adding event handlers to an extender. Like in the linked post above, I will search for an extender, and then wire up an event hander and that's about it. And for this post I'm going to provide another simple example of that, but there's a few other reasons you might want to poke around a component. One such case is the "_layout" function of the ModalPopupExtender. In the 10618 release I encountered an annoying side effect with the changing the innerHTML of a ModalPopupExtender. Any time that I swapped the content dynamically, it would reposition the Modal. This is on one hand a desired behavior, but I would also be nice to turn it off, so here's a little script I used to solve that issue.
<script type="text/javascript">
var extenderID = null;
var extender = null;
var _doLayout = true;
function hideSet(sender, args){
var cncl = confirm('Are you sure you want to close?');
if (!cncl){
_doLayout = true;
args.set_cancel(true);
}
}
function reg_init(exID)
{
if (!extender){
extenderID = exID;
Sys.Application.add_load(init);
}
}
function init(){
if (!extender){
extender = Sys.Application.findComponent(extenderID);
extender._lyt = extender._layout;
extender._layout = function layoutExtension(){
alert('a');
if (_doLayout && this._lyt)
{
alert('g');
_doLayout = false;
this._lyt();
}
};
extender.add_hiding(hideSet);
}
}
</script>
Called in code behind:
ScriptManager.RegisterStartupScript(this, GetType(), "main", "reg_init('" + FindThisModalExtender.ClientID + "');", true);
Basically I'm just pushing the original _layout function into a new bucket, and adding a check to see if I really want to perform a layout. It's a pretty simple and sometimes useful trick, the big downside is that I'm violating the implied convention that all JS variables, and functions that start with "_" are private, and subject to change. In reality what I should do is open up the toolkit and give myself a public hook, except that in the end, my implementation will be just as fragile. When I update to a new version of the toolkit, I either would have to possibly redo my hack or possible redo my customization of the ModalPopupExtender depending on what's been fixed or changed in the toolkit. What's the this in this.
Next on the docket is a rough outline of the University Domain area. Basically it will look something like this (sometimes those class diagrams are pretty handy).
But here's another set of tough choices to make along the lines of Parentage. For instance, are the People a property of the University, or College to which they are associated? Probably not, but the only way to tell would be to get some more clarification on how this data is likely to be used by my eventual fictional application.
If this system were to back a national university ranking system, it might just be that the majority of the time when an end user is working with the University Domain object they will in fact be working with its entire set of students. Only I'm not really designing this for an oddball case like that one, which leads me to a more basic question: Why am I doing this, or more importantly where are we going with this?
Sure I'm working to make a canned Domain so I can explore new technologies, but I do have a more immediate goal in mind. When I complete this series I'm first going to put together a simple Class Registration system first in Silverlight and then in Ajax.ASP.Net to show some of the pros and cons of each. Mainly I'm going to use the more polished Dynamic Modal covered here to drive a Grid based application.
That said, when I think about the choices of developing relationships for my Domain objects, I realize that at least initially this Domain set should really be focused on the StudentStatus, StudentHistory, EmployeeStatus, EmployeeHistory and Class objects. To really flesh out this domain I need to get a full understanding of these objects. Then I'll double back on my University hierarchy and person hierarchy.
So here's my initial pass at the first object in that chain Student Status.
All I'm shooting for here is to capture, what person, what classes, and what what's the state of the schedule. This data will be augmented by History records and by a StudentRecord that will act as the link between the College and the student.
As a general note I'm planning to switch to these class diagrams, they're a lot more meaningful that the ugly code snippets I've been using and at least for the next new posts nothing interesting is going into the code anyway.
In all my cross-posting, I forgot to include the conference schedule indicating which classes and workshops we attended. Here it is for reference.
The following table details the schedule for the conference. I've highlighted the talks and workshops that Laura attended as well as those I attended to show our coverage of the available material.
| Pre-Conference Workshops - Monday, October 15th 2007 |
9:00am-
6:00pm |
Architecting ASP.NET Applications
Paul Sheriff |
SQL Server 2005:
Power to the Developer
Brian Randell |
Making the Tough Choices: Selecting the Right Techniques for Your App
Deborah Kurata |
|
| Conference Day 1 - Tuesday, October 16th 2007 |
| 9:00am |
Keynote: The Trusted Platform for Your Business:
Windows Server, SQL Server, and Visual Studio |
D. Britton Johnston, Product Unit Manager, SQL Server,
Joseph Landes, Director, Windows Server,
Dave Mendlen, Director, Visual Studio |
| |
ASP Live! |
TFS Live! |
.NET 3.0 Live! |
| 10:30am |
Creating a Custom ASP.NET DataSource Control
Rocky Lhotka |
Understanding the Update Panel
Scott Cate |
Managing Software Releases with Visual Studio Team System
Chris Menegay |
Beyond .NET 3.0: Vista and the Managed Developer
Brian Randell |
| 11:45am |
What ASP.NET Developers Should Know about JavaScript
Scott Allen |
Building ASP.NET Database Applications with Nhibernate
Benjamin Day |
Customizing Team System Projects
Brian Randell |
Implementing SOA Design Patterns With WCF
Rob Daigneau |
| 12:45pm |
Lunch |
| 2:00pm |
Using ASP.NET AJAX Extenders to Enhance Existing Sites
Miguel Castro |
Using Windows Workflow Foundation in ASP.NET
Michiel Van Otegem |
Serious Team Foundation Server Customization
Benjamin Day |
Windows Presentation Foundation: Making It Real
Billy Hollis |
| 3:15pm |
Build a 3-tier Data Driven Website
Chris Franz |
Debugging MS Ajax
Scott Cate |
Team System Futures
Chris Menegay |
Windows Communication Foundation (WCF) for .ASMX and Remoting Developers
Richard Hale Shaw |
| 4:30pm |
MS Ajax Under the Hood
Scott Cate |
Create Scalable Apps with Asynchronous Processing
Michiel Van Otegem |
Serious Team Foundation Server Source Control
Benjamin Day |
Introduction to Microsoft Windows Workflow Foundation
Michael Stiefel |
5:45pm-
7:30pm |
Exhibitor Reception - on the exhibit floor (Brasilia) |
| Conference Day 2 - Wednesday, October 17th 2007 |
| 9:00am |
KEYNOTE: The Microsoft Data Platform and the
Data Programmer Experience |
D. Britton Johnston, Product Unit Manager,
Data Programmability Tools, Microsoft |
| |
ASP Live! |
TFS Live! |
.NET 3.0 Live! |
| 10:30am |
Building Smart Tags & Property Builders for Your Windows or Web Controls
Miguel Castro |
AJAX at Scale
Mark D'Urso &
Allen Wagner |
Making Attributes and Reflection Work for You
Ken Getz |
Creating Custom WCF Behaviors
Rob Daigneau |
| 11:45am |
ASP.NET Master Pages - Tips, Tricks and Traps
Scott Allen |
Move over Flash, here comes Silverlight - Lush UI for ASP.NET Developers
Walt Ritscher |
How to Do a Code Review
Billy Hollis |
Building Custom Controls in WPF
Mark Miller |
| 12:45pm |
Lunch |
| 2:00pm |
Serious ASP.NET WebPart Customization
Benjamin Day |
Configuration Files for ASP.NET 2.0
Robert Boedigheimer |
Understanding Delegates and Events
Ken Getz |
Using the Windows Workflow Foundation Rules Engine as a Stand-alone Rules Engine
Michael Stiefel |
| 3:15pm |
Exploiting the ASP.NET Adapter Architecture
Robert Boedigheimer |
Real World Exception Handling in ASP.NET
Walt Ritscher |
More Best Kept Secrets in .NET
Deborah Kurata |
WPF with Expression Interactive Designer and Visual Studio
Billy Hollis |
| 4:30pm |
ASP.NET 2.0's Data Binding Features
Ken Getz |
IIS 7 for Web Developers
Robert Boedigheimer |
Best Practice Architecture: Layering Your Applications
Rocky Lhotka |
Best Practices for Designing and Building SOA Applications with WCF
Richard Hale Shaw |
| Post-Conference Workshops - Thursday, October 18th 2007 |
9:00am-
6:00pm |
Advanced C#: Moving up to LINQ, WCF and Framework 3.5
Richard Hale Shaw |
Getting the Most Mileage out of Team System
Benjamin Day |
Build Distributed Object-oriented Apps in .NET 3.0
Rocky Lhotka |
|
Roles? This is definitely one of the areas I've had the most trouble with when I try to understand my fictitious Plebian U Domain. In my original model, roles defined both a person's relationship to the University either employee (of a specific type ex, Professor, Adminstrator, GroundsKeeper etc) or student (graduate, undergrad, post-grad), and status/ fulltime and part time. On my original person object there was no concept of a Roles list (it was build on .Net 1.1, so no generics). The way I had built my layers, the BLL would call into the DAL with a specific RoleID and get back a list of all people in that role.
In this retouching of my Bag-O-Tricks I'm planning on using LINQ in the BLL to make those types of selections. This gives me 2 benefits, 1st if a person does have multiple roles I know long will need to load the same exact person record up more than once, and second I think I'll be able to simplify the scope of the Role domain object. The big problem that I've always had with my original approach is that I felt that the Role object was really trying to encapsulate 2 distinct pieces of data. 1st the PersonToUniversityRelationShip and 2nd the PersonEmploymentType or PersonStudentType. Right now I'm basically looking at Role to define a person as an Employee, a Student or both.
In fact I'm not even sure that I'll have a Role object in my finalized Domain, in some ways it's a vestige of past incarnations, like the appendix, that while it might not cause any issues may not serve any real purpose. The data that I'm really going to care about is going to shift to two new domain objects tentatively called PersonEmploymentStatus and PersonEnrollmentStatus. I'm inclined at least at the Database layer so that I can use FK's to constrain the values. The status tables will let me define the attributes like type of Employee as well as more detailed information like what Colleges is the person associated with.
I'm not entirely sold on this yet, but I think that in the end I will go away from using Roles and just use LINQ to JOIN the Status objects with the Person objects to get the specific Employee and Student records. Some of that will be shaken out when I start to flesh out the Status objects and see how they relate to the EmplomentHistory and StudentHistory records that I had in my original Domain set, but I'm not in too much of a hurry to choose, the PersonRole class I have is very small, and using the Generate Unit Tests facility of VS 2008 Beta 2 makes very short work of the unit test for these objects.
Currently I have only this for my PersonRole object:
public class PersonRole
{
public int? RoleID { get; set; }
public string RoleName { get; set; }
public string RoleDescription { get; set; }
public PersonRole()
{
}
public PersonRole(int? roleID, string roleName, string roleDescription)
{
this.RoleID = roleID;
this.RoleName = roleName;
this.RoleDescription = roleDescription;
}
}
thing that has always been difficult for me when I try to extract the individual entities from the domain, is knowing just how far to break things down. Think about something like a Date, in truth a Data can be thought of as three separate objects, a Month, Day and Year. In fact it wasn't on common in the days before Ajax Calendars to create a Data as either 3 separate Text-Boxes or Drop-Down Lists. Sure on the server side these fields are usually recombined to create a full Date object, but it's not inconceivable to consider the constituents as independent objects, especially for specific validation requirements, like verifying that a Date is on a Monday or Thursday.
Now I have never seen, nor would I ever recommend splitting out the a Date into 3 separate Domain objects. However I have seen ActivityDate as a fully fledged Domain object. Every table that needed to store an Activity Data would make an entry In the FKeyed Activity table, and the ActivityDate consisted of a UserID, DataTime and ActivityID. In this case the abstraction made some sense based on the reporting requirements of the System. One report that was given a very high deliverable rating was the ability to at a glance see what employee had performed what actions for a given Date Range. Sure each table could have an ActivityDate field, and some report could do multiple selects and compile the results, but for both efficiency and ease of maintenance it made sense to create a fully fledged entity. It made even more sense to push this into the Domain, as it made it very clear to all consumers of the Domain objects that the Activity tracking was really a first class object.
For this project both the first time I looked at this, and this time the Roles area really was one of the places where I struggled the most to find a clean set of fault-lines to traverse. Sure there were other areas where I could vastly improve my design, but none where I felt quite as unsure. Hopefully as I work into the BLL of this project I will start to recognize the signs of a good clean set of domain objects.
This is a little interruption to cover something that's on my mind a lot lately. One of the more interesting attributes of a truly good web developer is design based on what's possible. The web is a much more fickle place than a database. There are hard predictable albeit often confounding reasons that govern the way databases work. The web, while still mostly governed by reason and known rules of invocation, has an edge of unpredictability. Partly this is due to differing interpretations of standards "compliance" helped along for better or worse with Microsoft's strong tradition of backward compatibility, but partly this is due to number of layers that exist between users and the systems that they are working against.
Think about a group of dominoes standing on edge all spaced perfectly to create a chain reaction of falling down when the one is knocked done. If you're like me you've tinkered with making these elaborate chains of dominoes to both test your ability to plan and execute as well as just the pure fun of seeing things fall. Setting up dominoes to be knocked down can become a pretty elaborate task, but as long as you can see all of the dominoes and insert appropriate checks to prevent unintended consequences it's not terribly hard, just tedious. But what happens if you're not able to see certain dominoes, or stretches through which the dominoes will pass. How do insure there are proper checks, how do you verify the spacing to insure that there won't be a break in your chain. What about possible recovery plans in case there is a collapse, or a break in your chain?
The trouble with the web is that there is so much that is out of your hands. On the one hand, it's a fantastic benefit that someone has worked out the very complex issues of network communication; on the other hand you have to work with its inherent limitations. This type of uncertainty often leads to prototype heavy architecture, or at least is should. Sure you can take applied knowledge to a new problem and do a fair amount of traditional upfront architecture, but in reality web development for better or worse often starts at the level of the Wire Frame or the Mocked up website.
You can see this effect in the current blog series that I'm working on, where I'll be somewhat unconcerned with nailing down the absolutes of a pattern, and more interested in getting something I can work with in a real User Case to fully flesh out the design. There's definitely an air of XP to it, but it's not pure XP. I like test driven, and XP, but I think it's sometimes slower than it needs to be. There are some things you just know as a developer, especially after a few years of coding, so there are just going to be those things where it's better to code an unit test in a more fluid manner than is often implied by XP.
The idea is basically to start with what can be done and code/design back to how it should be done. This approach can influence every layer of the application, from how domain properties are grouped to the thickness and groupings of the BLL, to the type of Data access Layer that best fits the UI. And as much as this goes against the vast majority of literature on good design, I does work, most of the time.
The key to this equation is the disposability of the web. A website can become out-dated in 2 years, and borderline obsolete in three. Sure good Designer work can buy you a little more life time, but the User facing portion of a website has a very short shelf life. And while the backend can certainly outlast the thrashing of UI level intricacies, there's a lot of pressure on back ends of websites to implement the latest and greatest pattern from the ever churning best practices mill.
The thing that strikes me as the good in this approach is the focus on possibility and the built in recognition that flexibility is paramount to success, but the negatives are vast and deep. The primary among these is the combination of a company's and a developer's ability to stay committed to a project. If they are committed, the developer can fully evolve their creation into a healthy maintainable state, but as I'm sure you know, all too often, the effort peters out long before the project reaches any sort of maturity. Either the customer needs it yesterday, or the developer gets feed up the management BS that stands between him/her and doing things right.
So I guess I'm saying that I'm dubious about the WWW approach to design, but that I think that it's been a very useful contributor the world of enterprise application design, and that I recognize that the things that I do on my way to an answer may not always be the most intuitive, but they are part of a honed process of randomness that is web development. Just a thought…
So how to handle contact info, do I make a "type level" domain object like an Emergency or Home, or do I save that sort of logical grouping for the Business layer. Truthfully I've already made up my mind. The domain layer I'm updating doesn't make any groupings, and here's why. Essentially I tried to look at the domain objects as whole entities onto themselves. An email address really has nothing to do with a mailing address, and any association like "emergency" is purely a matter of interpretation. Another way to look at it is I didn't really want my domain layer making what I thought was a business decision to allow something like an emergency email. It's the prerogative of the BLL to decide what Types of each entity the system can created. Perhaps for the grouping of emergency the BLL determines that Phone-Number is the only valid entity to create and maintain.
So if that sounds like a reasonable approach then it's not too hard to draw out where I'm going next. One change I've made though is to switch to Nullable<int>s for my IDs. I originally created this domain set in .Net 1.1 so that really wasn't a possibility. But now that I can, it can become a nice way to track new domain objects that must be persisted. This brings up a whole entire ball of scariness I haven't yet covered, how to track the dirty state of an Domain object, let me count the ways. First and foremost let me say that this is the sole potential benefit that I see in using DataSets instead of Domain objects, but it's not worth it by any means.
Handling the notion of a Dirty object, is a touchy one topic, both because it can provide a fair number of challenges, and because there are so many preferred patterns to use. However generally I tend to cheat here especially when it comes to making any decision about whether to persist/update/delete a domain object I rely solely on the BLL to make the call. Because I generally try to follow a pattern where any UI, or API that can create or modify data has absolutely no contact with domain objects, I can push any state logic out of the domain layer allowing for a very simple model. I can't say if this is the best model, only that I like idea that a least one application layer can be very simple.
So without further ado here's the ContactInfo Class and its constituents:
public class ContactInfo
{
public int? ContactInfoID { get; set; }
public List<PhoneNumber> PhoneNumbers { get; set; }
public List<Address> Addresses { get; set; }
public List<EmailAddress> EmailAddresses { get; set; }
public ContactInfo()
{
}
public ContactInfo(int? contactInfoID, List<PhoneNumber> phoneNumbers, List<Address> addresses, List<EmailAddress> emailAddresses)
{
this.ContactInfoID = contactInfoID;
this.PhoneNumbers = phoneNumbers;
this.Addresses = addresses;
this.EmailAddresses = emailAddresses;
}
}
public class EmailAddress
{
public int? AddressID { get; set; }
public string Address { get; set; }
public Status Status { get; set; }
public int Order { get; set; }
public EmailAddress()
{
}
public EmailAddress(int? addressID, string address, Status status, int order)
{
this.AddressID = addressID;
this.Address = address;
this.Status = status;
this.Order = order;
}
}
public class PhoneNumber
{
public int? PhoneNumberID { get; set; }
public string Number { get; set; }
public PhoneNumberType PhoneNumberType { get; set; }
public PhoneNumber()
{
}
public PhoneNumber(int? phoneNumberID, string number, PhoneNumberType phoneNumberType)
{
this.PhoneNumberID = phoneNumberID;
this.Number = number;
this.PhoneNumberType = phoneNumberType;
}
}
public class Address
{
public int? AddressID { get; set; }
public AddressType AddressType { get; set; }
public string Street { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Zip { get; set; }
public Address()
{
}
public Address(int? addressID,
AddressType addressType,
string street,
string city,
string state,
string zip)
{
this.AddressID = addressID;
this.AddressType = addressType;
this.Street = street;
this.City = city;
this.State = state;
this.Zip = zip;
}
}
That's it not too much there, but next we'll look at the Roles side of the Person Tree.
Okay one more distraction, although I'm not yet focusing on unit tests, I'm going to include some code that I often use to support my unit tests. This class is used to create a default instance of a complex object. With my current code base I don't have a lot of use for it, but I'd like to throw it out there as I know it will be useful to me later, and hopefully someone will be able to turn it into something much more useful.
Object Creator
public class DefaultObjectCreator<T>
{
public DefaultObjectCreator()
{
if (_propertyValues == null)
{
_propertyValues = new Hashtable();
}
_objectType = typeof(T);
}
public DefaultObjectCreator<T> CreateObject()
{
Assembly asm = Assembly.GetAssembly(_objectType);
List<object> args = new List<object>();
ConstructorInfo ctor = selectConstructor(_objectType);
if (null == ctor)
{
throw new ApplicationException("Could not match provided parameters to any Constructor");
}
foreach (ParameterInfo pi in ctor.GetParameters())
{
if (_propertyValues.ContainsKey(pi.Name))
{
args.Add(_propertyValues[pi.Name]);
}
else
{
args.Add(getDefaultTypeValue(pi.ParameterType));
}
}
_createdObject = (T)asm.CreateInstance(_objectType.FullName, true, BindingFlags.CreateInstance, null, args.ToArray(), null, null);
return this;
}
public DefaultObjectCreator<T> SetValue(string paramName, object value)
{
if (null == _createdObject)
{
_propertyValues[paramName] = value;
return this;
}
foreach (PropertyInfo pi in _objectType.GetProperties())
{
if (pi.Name.ToLower() == paramName.ToLower())
{
pi.SetValue(_createdObject, value, null);
return this;
}
}
foreach (FieldInfo fi in _objectType.GetFields())
{
if (fi.Name.ToLower() == paramName.ToLower())
{
fi.SetValue(_createdObject, value);
return this;
}
}
throw new ApplicationException(string.Format("Could not find property [{0}]", paramName));
}
public