-
You may remember the last time this happened. Well, it’s here once again. I’ll be away from the office, off of email – and more importantly, not processing your article submissions from 6/22 – 7/20. Feel free to go ahead and submit them to mmsubmit@microsoft.com – just don’t expect a response until after I get back and get through the mounds of email that I will inevitably have.
We’ll be traveling all over this time, from St. Louis, MO to Houston, TX to Birmingham, AL – so if you’re in any of those cities, maybe I’ll see you around!
-
I’m sitting here in my hotel room at MIX 2009, where a ton of really huge announcements were made today. In a much more scaled down attempt at continuing that tradition, I want to announce that starting in May, we are launching a 9 week series focused on introducing ASP.NET Web application developers to creating rich internet applications – and introduce a few other patterns along the way to help create better Web software.
The approach will take an existing Web application that has been written in classic ASP.NET and refactor parts of it based on the goals of each installment. Some of the specific details are still being worked out, but I wanted to take this opportunity to introduce you to James Kovacs, the guy who’s going to be working them out, hopefully with some help from you. I’ll let James post separately on his thoughts and initial items that he would like feedback on, but wanted to at least be the first one to tell you all how excited I am about this upcoming series!
-
Well, kind of. One of the things I’ve realized as I’ve watched the traffic patterns for this blog is that you good folks come here more out of interest for stuff related to MSDN Magazine (or actually, thanks to the long tail, developer certifications). That, combined with an invitation from a community of folks that I both highly respect and also consider to be friends outside of work, has prompted me to move my more technical-style posts over to the CodeBetter community. You can find me there at http://codebetter.com/blogs/howard.dierking/. I’ll continue to post magazine-related topics here and may actually expand that a bit (if you’re looking for certification topics, please check out Gerry O’Brien’s blog) – but if you’re interested in what I have to say with respect to software design and coding, please update your links to my new home at CodeBetter.
-
Especially when you were unaware that apparently, you’re being moved to China.

-
In my last entry, I mentioned that I was back in the office because of the recent events in the economy. Even with that, I realize that I’ve been pretty sluggish with respect to blogging – probably uncomfortably sluggish for those of you waiting on my to review your article submission.
But really – I had good reason! On January 24th, my wife and I welcomed Sarah Katherine into the world.
Now, I’ll get right on those article submissions…
-
Well, as it turns out based on recent economic events, it doesn't make as much sense for me to go off on parental leave in February. Therefore, I will be back to reviewing articles shortly. Perhaps I'll even find the time to do some technical blogging again...
-
I know it's been a while since I've blogged. It's not because I don't have a lot of stuff to say - I just haven't really had time to sit down and write it all out (I seem to remember Glenn actually having this same problem - perhaps I'll have to try his approach for being a more effective blogger.) At any rate, this post is more of a news bulletin to let you know that if you submit an article idea any time in February, it will likely go unanswered until March. The reason is that I will be off on parental leave taking care of a new little girl (actually, I'll be the one taking care of her sister while mom takes care of the newborn).
At any rate, I wanted to make sure and let you know so that you wouldn't assume that a lack of response on our part indicated a lack of interest in your article idea.
-
-
We're currently in the process of stepping back and taking a critical look at our Web site to see how you all are using it - and how we can redesign parts of it (big or small) to make that experience better. We are continuously receiving your feedback on existing frustrations and we are working hard to remedy those (as a general fyi, most of the frustrations have to do with navigation). However, in order to get a sense of whether we need to look at some of the more fundamental metaphors for the site experience, we have created a short survey which seeks to get an idea of the types of tools and degrees to which you interact with some of the modern social Web applications.
You can access the survey here. It's only 8 questions, so it shouldn't take more than 10 minutes.
Thanks in advance for helping us to create a better online experience for you.
-
I received my monthly progress report today on how good a job you all feel we're doing on the MSDN Magazine Web site. In short, it seems like the numbers are down a bit from last month, and in culling through the verbatim responses, there was one theme that I was surprised about. Many people that responded to our survey said that they wanted more code.
I have to confess that I need some help clarifying this one. Nearly all of our articles have code in the body of the article - and at least 1/3 of them have a complete sample application that can be downloaded as reference.
So can you help me better understand the "more code" request here? Are you guys wanting...
- more articles with complete sample applications?
- more code displayed in the body of the article?
- better integration of our code explorer tool with the article?
- something else entirely??
-
One of the fun aspects of my job is that I get to work with some really brilliant folks - and every now and then they give me the opportunity to participate in some of the things that they are involved with. One of those cases as of recent is the 6th International Conference on Information Technology. Test Run author, Dr. James McCaffrey is heading up the software testing track for the conference and invited me to also participate as a track chair.
Check out the software testing track description here, download the template for submitting a paper, and send it to James here.
-
So firstly, let me just answer the question that I'm sure you're asking: No. We weren't able to get Xzibit.
(seriously though - X - If you want to break into the software game - email me...)
With that out of the way, I did want to let you know about a sweepstakes that we are sponsoring in partnership with TechWeb. As with any sweepstakes, the game is simple - go to the website and register. That's it. At the end of the day, we're going to be giving away up to $10,000 in software from a variety of different companies. Check out the website for more information.
-
Architecturally, I lean pretty heavily towards 2 philosophies - Domain Driven Design and the Rich Domain Model pattern. And while neither requires the other for success (contrary to much of what you read out there), they seem to work well together for me, and hence, I have internalized them into a single approach for building solutions.
As a result of my approach, I typically start with (and end up with) an assembly for my domain model (another assembly for my domain model's automated unit tests), an assembly for my presentation logic, and an assembly for my data access layer - or where to put it into DDD terms, the layer where my repository objects live. There is an ongoing debate about how the assembly references should look - I'm not going to get into the nuances of the arguments, but these seem to be the 2 basic philosophies:
- Have the data access assembly reference the domain model assembly with the UI layer referencing both (and calling the repository objects directly to get domain instances)
- Have the UI layer reference only the domain model assembly reference and have the domain model objects call their respective repository objects in the data access layer
There are a couple other more specific approaches, but I think that those give you an idea of the underlying philosophies. I tend to gravitate towards philosophy #1, though I'm much more comfortable with #2 when done in conjunction with a DI container like Windsor.
So there you have my general layering philosophy - UI talks to repository to get and work on domain objects. Why is this important? Because one of the cases that has always made me a little uncomfortable is the classic case where I need to generate a UI element like a grid and I don't need to bring back the entire domain object (or in DDD terms, the entire aggregate). The 3 major approaches I have seen and used are:
- Return a IDbDataReader instance from the appropriate repository object in the data access layer
- Fetch all of the relevant results into an in-memory data structure in the data access layer and hand that back to the caller
- Use a SqlDataSource object at the UI layer and configure it with all of the proper query information
I don't really like any of these solutions. The problem with solution #1 is that once you pass the stream reader out of the scope where it was initiated, you are relying on the consumer code to close the reader. The problem with solution #2 is that you're potentially buffering a lot of data that is going to be almost immediately discarded. The problem with solution #3 (which is the one I have ended up using most frequently) is that it puts you in a situation where you are managing data access in multiple places.
So I was thinking the other night that the ideal solution would be one where I could, in the same scope, manage the lifetime of my stream reader object, but still hand back some kind of safe reference to that stream to calling code - and then I remembered that really cool C# iterators feature that I had thought was nifty but very rarely used. I added the following method to my repository class (DB is standard AdventureWorks - ignore the horrible practice of not parameterizing my query).
public class ProductsRepository
{
private const string COMMAND_TEXT =
"select top {0} ProductID, [Name] from Production.vProductAndDescription where CultureID = 'en'";
public static IEnumerable<object> GetProducts(int numberRecords) {
/*
* in this example, numberRecords is a very simple illustration
* of how you could expose more complex criteria parameters based
* on the specific domain
*/
using (var conn = new SqlConnection(Settings.Default.AdWksCN))
using (var cmd = conn.CreateCommand()) {
cmd.CommandText = string.Format(COMMAND_TEXT, numberRecords);
conn.Open();
using (var rdr = cmd.ExecuteReader()) {
if (rdr != null) {
while (rdr.Read()) {
var productID = rdr.GetInt32(0);
var name = rdr.GetString(1);
yield return new {productID, name};
}
}
}
}
}
}
Note the yield return statement - when the compiler sees this, it generates a whole other class that implements IEnumerable<object> and contains the code in your method along with a whole bunch of other code to manage the enumeration activity. For example, here's the code for the MoveNext method of my generated enumerable class (ala Reflector).
private bool MoveNext()
{
bool CS$1$0000;
try
{
int CS$4$0001 = this.<>1__state;
if (CS$4$0001 != 0)
{
if (CS$4$0001 != 4)
{
goto Label_0127;
}
goto Label_00F7;
}
this.<>1__state = -1;
this.<conn>5__1 = new SqlConnection(Settings.Default.AdWksCN);
this.<>1__state = 1;
this.<cmd>5__2 = this.<conn>5__1.CreateCommand();
this.<>1__state = 2;
this.<cmd>5__2.CommandText = string.Format(
"select top {0} ProductID, [Name] from Production.vProductAndDescription " +
"where CultureID = 'en'", this.numberRecords);
this.<conn>5__1.Open();
this.<rdr>5__3 = this.<cmd>5__2.ExecuteReader();
this.<>1__state = 3;
if (this.<rdr>5__3 != null)
{
while (this.<rdr>5__3.Read())
{
this.<productID>5__4 = this.<rdr>5__3.GetInt32(0);
this.<name>5__5 = this.<rdr>5__3.GetString(1);
this.<>2__current = new { productID = this.<productID>5__4, name = this.<name>5__5 };
this.<>1__state = 4;
return true;
Label_00F7:
this.<>1__state = 3;
}
}
this.<>m__Finally8();
this.<>m__Finally7();
this.<>m__Finally6();
Label_0127:
CS$1$0000 = false;
}
fault
{
this.System.IDisposable.Dispose();
}
return CS$1$0000;
}
If you don't go cross-eyed from reading the compiler's choice of variable names, what you can see here is that the generated enumerator runs the query the first time MoveNext is called, then for subsequent calls, it simply calls the Read method on the data reader and returns the data elements extracted from the row. When it is done enumerating, it cleans itself up, which includes calling the rest of the cleanup code you defined in the body of your method.
So what's nice about this approach? Well, first and foremost, I can keep all of my data access code, including projection style queries with potentially complex criteria, in the same place as my object persistence data access code. At the same time, since I'm returning IEnumerable, I still retain all the benefits of a simple usage pattern (including data binding). For me, this is a nice hybrid solution for many of those cases where you just need to get a little off the rails!
-
I've been spending many of my recent developer cycles writing console applications to perform various tasks in an ETL process. And yes, before you ask, I had started out initially modeling my ETL process with SSIS - and while I could eventually get it to do what I wanted, at the end of the day, regular code was a more direct and expressive syntax for describing my process.
Anyway, one of the recurring things that I found myself having to do as I was writing these little command line apps was parsing various command line arguments - whether they were positional parameters, optional (named) parameters or switches. I refactored that args-managing logic out into its own class and wanted to share it with you in the case that you find yourself rewriting similar code in your applications. One of the things that you'll notice is that the error handling code is pretty sparse, and I could have made it even more robust by supporting different arg formats instead of hard-coding the delimiter characters. Perhaps one day...
internal class CommandLineArgs
{
private readonly IEnumerable<string> _args;
public CommandLineArgs(IEnumerable<string> args) {
_args = args;
}
public bool GetSwitch(string switchName) {
var swt =
_args.FirstOrDefault(
a =>
a.Equals("/" + switchName, StringComparison.InvariantCultureIgnoreCase) ||
a.Equals("-" + switchName, StringComparison.InvariantCultureIgnoreCase));
return !string.IsNullOrEmpty(swt);
}
public T ParseParam<T>(string param) {
var paramString = _args.FirstOrDefault(s => s.StartsWith(string.Format("/{0}:", param)));
if (string.IsNullOrEmpty(paramString))
throw new ArgumentException(
"The requested argument was not found in the command line arguments.", param);
var paramValueString = paramString.Split(':')[1];
return GetTypedVal<T>(paramValueString);
}
public T GetArgAt<T>(int position) {
var val = _args.ElementAt(position);
return GetTypedVal<T>(val);
}
private T GetTypedVal<T>(string val) {
try {
return (T) Convert.ChangeType(val, typeof (T));
}
catch (Exception ex) {
throw new ArgumentException(
"Argument value [" + val + "] could not be parsed into type [" + typeof (T).Name + "].",
ex);
}
}
}
-
SharePoint is one of those technologies for me that is large enough in scope and ambition that I am simultaneously in awe of it and confused by it. To elaborate on the confusing aspect, SharePoint feels like it has multiple masters - more specifically, it's hard to know who should be paying attention to it. Is it a system admin type of product? Is it a developer platform? Is it a collaboration portal for use by regular users. The answer, which speaks both to the power and the confusion, is "absolutely yes".
I personally buy into the vision of SharePoint as a web application platform. I don't think we're there yet, but it makes a lot of sense to me that we'll get there. That said, it's still really confusing as a developer to know where to get started with SharePoint (although Ted has done a fantastic job at trying to help dense folks like myself). I was recently forwarded an email, however, with some great resources for getting started as a developer. First, there's the Web site http://www.microsoft.com/click/SharePointDeveloper/ - there are a lot of great jumping off points here. There's also a great set of getting started Webcasts. For more information on that, check out Paul's post.
Check it out.