Welcome

You have reached the blog of Keith Elder. Thank you for visiting! Feel free to click the twitter icon to the right and follow me on twitter.

Creating Custom SQL CLR User-Defined Types

Posted by Keith Elder | Posted in .Net, SQL Server | Posted on 29-10-2007

6

Since SQL Server 2005 .Net developers and DBAs have had the ability to create custom SQL CLR types.  It wasn’t until recent I found a few uses for them.  Not only did I find a use for them but a DBA who is a team member did as well.  If you would like more information about SQL CLR types or are new to them start by reading the introduction here.   What follows is a walk through from start to finish creating a user-defined type (UDT).   The project source code is available at the end of the article.

Maintaining Data Integrity

One of the advantages of SQL CLR User-Defined Types is the ability to store complex information in SQL Server and guarantee the integrity of the data.  For example, let’s say a database is fed information from an SSIS package at night that has to move email address information from one system to another.  How would one guarantee the email address field is valid as it is moved from system A to system B?  Obviously that would have to be build that into the SSIS package somehow.  But does that “really” guarantee another SSIS package a Jr. Database Engineer wrote does the same validation?  No it doesn’t.  Removing SSIS packages from the equation we still have to worry about end-user input and hope our developers from various teams or platforms follow the same validation rules.  It is a tough balancing act to say the least.  Having data integrity close to the data store has its advantages since everything coming into the database must pass the data integrity spec.  This is where a SQL CLR User-Defined Type can come into play.  Instead of creating a column to store email address in a type of varchar(50) or whatever your company uses as a design standard, we could create a SQL CLR User-Defined Type of “EmailAddress”.  Within the .Net runtime we could easily validate the integrity of the email address and throw an exception if it doesn’t match.  We could also split apart the domain and prefix values if we wanted to pull out all email addresses for the domain keithelder.net.  Let’s look at an example.

Creating Your Project

To get started creating a SQL CLR type we first need to create a project that understands how to build SQL Server types.  To do this open up Visual Studio and point to Database Projects (assuming you installed the database components) and select SQL-CLR.  Then chose the language for your project.  In our case we are going to select C#.

image

After the project is created the first thing to do is to create a folder to store the various types.  It isn’t wise to just start adding different CLR types to the project, things will get messy.  Right click the project and add a folder called “Types”.

After you’ve added the folder, right click the folder and click “New Item”.  Select User-Defined Type from the menu and give your type the name of the type you want displayed in SQL Server (important).

image

In this example I am calling the type “EmailAddress”.   Once entered click add.

Project Cleanup

After the custom user-defined type is added to Visual Studio the code should look like this.

using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;

[Serializable]
[Microsoft.SqlServer.Server.SqlUserDefinedType(Format.Native)]
public struct EmailAddress : INullable
{
public override string ToString()
{
// Replace the following code with your code
return "";
}

public bool IsNull
{
get
{
// Put your code here
return m_Null;
}
}

public static EmailAddress Null
{
get
{
EmailAddress h = new EmailAddress();
h.m_Null = true;
return h;
}
}

public static EmailAddress Parse(SqlString s)
{
if (s.IsNull)
return Null;
EmailAddress u = new EmailAddress();
// Put your code here
return u;
}

// This is a place-holder method
public string Method1()
{
//Insert method code here
return "Hello";
}

// This is a place-holder static method
public static SqlString Method2()
{
//Insert method code here
return new SqlString("Hello");
}

// This is a place-holder field member
public int var1;
// Private member
private bool m_Null;
}


There are several things we do not need here as well as some refactoring we need to do.  Let’s clean things up a bit. 

First thing I suggest is to remove the Method*() methods.  They aren’t needed, they are just place holders.  The next thing is to refactor the m_Null variable.  Personal choice here but I can’t stand the naming convention of m_.  It irks me to no end.  It must die. 

The next thing we need to do is create a variable to hold our email address value.  Since our type is called EmailAddress I am going to call this new property Value.  After the cleanup is done we should have something similar to this.

using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;

[Serializable]
[Microsoft.SqlServer.Server.SqlUserDefinedType(Format.Native)]
public struct EmailAddress : INullable
{
private string _value;
/// <summary>
/// The email address value.
/// </summary>
public string Value
{
get { return _value; }
set { _value = value; }
}

public override string ToString()
{
return _value;
}

private bool _isNull;
public bool IsNull
{
get
{
return _isNull;
}
}

public static EmailAddress Null
{
get
{
EmailAddress h = new EmailAddress();
h._isNull = true;
return h;
}
}

public static EmailAddress Parse(SqlString s)
{
if (s.IsNull)
return Null;
EmailAddress u = new EmailAddress();
// Put your code here
return u;
}
}

Coding Our Logic

We are now ready to put in our own logic to validate our email address along with some other features.

To start with let’s add a method to the code to validate the email address.  In this example I am going to use a regular expression that simply validates the integrity of the data.  Notice I didn’t use the word “validates” because validation of an email and and data integrity are two different things.  Integrity just checks to make sure my data is in the proper format.  It handles finding problem email addresses liked @asdf.com or blah@ and so on.  Whether the email address is actually valid and it works is a totally different story that requires the use of business services.  This is not the point here.  We just want to make sure that if someone is going to store an email address in our database it adheres to some type of data integrity and that our database will not except any text a developer throws at it.  Think of it as “gate keeper logic”.

After we add our validation logic we are going to add a call in the Parse(SqlString s) method.  This is where we are going to call our validation.   The new code will look something like this:

public static EmailAddress Parse(SqlString s)
{
if (s.IsNull)
return Null;

EmailAddress email = new EmailAddress();
if (email.ValidateEmail(s))
{
email.Value = s.ToString();
return email;
}
else
{
throw new SqlTypeException("The email " + s.ToString() + " was not in the proper format.");
}
}

/// <summary>
/// Validates the email being passed in.
/// </summary>
/// <param name="email"></param>
/// <returns></returns>
public bool ValidateEmail(SqlString email)
{
bool isValid = false;
if (this.IsNull)
{
return true;
}

isValid = Regex.IsMatch(email.ToString(), @"^[\w-]+(?:\.[\w-]+)*@(?:[\w-]+\.)+[a-zA-Z]{2,7}$");
if (isValid)
{
return true;
}
else
{
return false;
}
}

Fixing Serialization

At this point if build our solution it will work.  However, if we right click our project and click “Deploy” it will fail with the following error.

image

The reason is we have the email address as a string and we also have the object attributed with the serialization of Format.Native.

[Microsoft.SqlServer.Server.SqlUserDefinedType(Format.Native)]

The native format can only store value types, not referenced types.  This means it is limited as to what we can use (bool, int, etc).  String is not one of these so we need to create our own user-defined format.  Don’t worry, it isn’t as hard as it sounds.  The first step is to change the attribute to this:

[Microsoft.SqlServer.Server.SqlUserDefinedType(Format.UserDefined,IsByteOrdered=true,MaxByteSize=8000)]

Set the format to UserDefined, the IsByteOrder to true and the MaxByteSize to 8000.  Setting the format to UserDefined allows us to then put our own logic in place.  We do this by implementing IBinarySerialize in our custom type as we’ll see later on.  The IsByteOrdered option set to true guarantees the serialized binary data can be used for semantic ordering of the information.  This allows us to use the same operations in SQL Server as in managed code.  See this page for all of the options this enables like creating indexes, group by and more.  MaxByteSize can only be as large as 8000 bytes so we essentially set it the largest value.  If you know the value is going to require less information, set it to that value.  Yes in this case 8000 is more than an overkill for email addresses but I put it there so I could explain that 8000 is the largest the value can be.  Important to know.

Once we have our attribute setup properly we need to implement the interface IBinarySerialize as I mentioned.  There are only two methods to this interface: read and write.   Since we only have one property we are going to be storing this is pretty simple.  Here are the two methods implemented.

   public void Write(BinaryWriter w)
{
w.Write(_value);
}

public void Read(BinaryReader r)
{
_value = r.ReadString();
}

Ready To Deploy

As you see creating our own user-defined format wasn’t that bad.  Only a few lines of code.   At this point the project should build and should be deployable to the database.   To deploy the EmailAddress type to the database right click the project in Visual Studio and chose “Deploy”.  After it is deployed it should appear in the User-defined types under the Programmability section within SQL Server Studio as follows.

image

Using Our UDT in A Column

Once the UDT is deployed into the database we can associate our new type as the “Data Type” with a column in the database.  If we create a new table we’ll see the new type in the drop down.

image

Cool!  Yes and now we start thinking about other UDT’s such as phone numbers, zip codes, and more.  Where do we stop!?

Using Our New EmailAddress User-Defined Type

Now that we have a table to put our emails in.  Let’s add some email addresses to it and start playing around.  I added four email addresses to mine to initially play with.  After the “fake data” is entered, do a “select * from Email” T-SQL query to see the results of the data.  It should look like this:

image

Whoa!  Yes, this is scary.  The reason has to do with the format the database is storing our data.  Since we were not able to use the native format we can’t see the data as expected.  If you reference the code after we cleaned up you’ll remember there was a “Value” property in our object.  The good news is we can use this property to get at and see our data.  Let’s rewrite our query using that property like this:

select EmailId, EmailAddress.Value as Email from Email

The result of running this will be:

image

This is why I chose the naming convention of “Value” for this field since it seems a little weird to type EmailAddress.EmailAddress or EmailAddress.Email.  It made sense to just ask for the value stored.  I hope that makes sense.

Checking Our Validation

Now that we are able to select data properly from our table let’s look at how our validation works.   Here is the SQL query we are going to issue to SQL Server.

INSERT INTO [CARI2].[dbo].[Email]
([EmailAddress])
VALUES
('fakeaddress')

Of course the email address of “fakeaddress” shouldn’t pass our data integrity.  If we run this command on our table the following error is generated.

Msg 6522, Level 16, State 2, Line 1
A .NET Framework error occurred during execution of user-defined routine or aggregate "EmailAddress":
System.Data.SqlTypes.SqlTypeException: The email fakeaddress was not in the proper format.
System.Data.SqlTypes.SqlTypeException:
at EmailAddress.Parse(SqlString s)
.
The statement has been terminated.

This is exactly what we wanted since this stops anyone from entering data into our database that doesn’t pass our integrity check.  This means that neither an SSIS package running in the middle of the night nor an end-user is able to insert erroneous information into our data store.  Business problem solved.

Advance Queries and Extension Properties

It is important to remember that our custom type is merely an object.  As with any object we can add methods or properties to that object.  Here are some examples to get your brain turning. 

Let’s start with the example looking up all users that are in the domain “keith.com”.   How would we do that?  The trick is to remember we have to reference the .Value of the column to get to the data (this was the public property we created).  If you keep this in mind then it is like any other query.  Here’s an example:

select EmailId, EmailAddress.Value as Email from Email where EmailAddress.Value like '%keith.com'

A side note, SQL Server Studio does not give you intellisense when typing so it is important whatever names you come up with you standardize on to not confuse your team members. 

What if we wanted to do a distinct lookup of domains or to print the domain or the prefix values of the emails for data mining purposes?  In these cases you can chose to add extension properties to your object.  Below is the code for two examples using the prefix and the domain.

    /// <summary>
/// The part of the email address before the @ sign.
/// </summary>
public string Prefix
{
get
{
string[] x = Value.Split('@');
return x[0];
}
}

/// <summary>
/// The domain of the email address.
/// </summary>
public string Domain
{
get
{
string[] x = Value.Split('@');
return x[1];
}

}

As you see we are using the Split method to split our email address string into two parts using @ sign.  Instead of doing the like clause the way did it above that can now be expressed like the following:

select EmailId, EmailAddress.Value as Email from Email where EmailAddress.Domain='keith.com'

We can also do this now:

select EmailId, EmailAddress.Domain as Domain from Email

Which would yield us this:

image

Or we can do a distinct lookup like this which provides us with a much cleaner T-SQL syntax.

select distinct(EmailAddress.Domain) as Domain from Email

While this is all neat and good let me point out that I haven’t done any extensive performance tests to see which method performs better so be sure you do that before using one over the other.

Updating Your User-Defined Type

So far it has all been shiny pennies up until this point.  Watch out though here comes a rusty washer.  

When you update your UDT you are going to have to drop the UDT from any columns that use it, and then redeploy and then re-add.  Obviously this can be scripted but it is a pain, especially if you are dealing with tables that have millions of rows so be careful.  If your only goal is to get data integrity you may be better off using a user-defined trigger instead.  The bottom line is to make sure your UDT doesn’t change or need to change once you deploy it.

Conclusion

That’s it folks, a start to finish nuts and bolts of building user defined-types in SQL CLR.  Wasn’t it exciting?  I hope this helps those that are investigating SQL CLR User-Defined Types.

 

 

 

 

Datasets vs Business Entities

Posted by Keith Elder | Posted in .Net, Smart Clients, Web Services | Posted on 26-10-2007

5

If you are an experienced .Net developer more than likely you’ve come to a cross roads of sorts in development over which object model to go with.  Do you use Strong-Typed Datasets or should you write your own business entities from scratch or generate business entities using an ORM.  A reader emailed me asking my opinion the other day and the very question was also raised on Twitter by Joel Ross yesterday as well.  Here are my words of wisdom on the subject matter to help you hopefully arrive at a conclusion which road you may want to travel.

Things to Think About

What are you going to do with the data?  This is the most important question to ask your self.  The reason is Datasets and business entities solve two different problems and where one makes life easy in one example it overly complicates the heck out of another problem.  Let’s take a simple scenario that any Smart Client developer may run into.  For example, let’s say you are instructed to build a search screen within your application and bind the results to a DataGridView.  The user interface should allow an end-user to search and return joined row data from the data store.  After the data arrives to the client the end-user needs the ability to filter, group, and sort the data within the client.  What do you do?  Here is a rough draft of what we need.

image

In this case my default answer is a plain Dataset.  There are a few things to think about in this scenario.  The first one is how often the screen data might change.  In the example above it is returning CustomerId, CompanyName and ContactName and ContactTitle to the end-user.  The question is how do we handle a simple change if the business requirement changes a month from now and we need to add a new column of Email to the result set?  Let’s look at the three options we could go with to tackle this scenario.  It helps to visualize it on paper.

  Non-Typed Dataset Typed Dataset Business Entity
Fastest Development Time   X  
Requires Custom Programming for filter and sort     X
Requires Re-deploying Client To Add New Column   X X
Requires Re-deploying Service To Add New Column X X X
Heaviest Payload X    

Looking at the table we see the non-typed Dataset has the fewest checks (one less).  While it isn’t the fastest to develop because we do not get all of the automatic pre-built bindings it is still pretty fast.  Much faster than the custom business entity.  Even then we still don’t have to write our own sorting and filtering routines nor do we have to redeploy our client.  Having to redeploy is the biggest cost to a business and should be taken very seriously when developing Smart Clients for the enterprise.  Downtime is not cool in any business, even if it only takes a minute for a ClickOnce app to be redeployed.  In this scenario all we’d have to do is change the way we fill our Dataset within our middle tier (services layer) and then send it down the wire.  This change could be made pretty much whenever we want without having to interrupt the business.  Notice we get the flexibility of being able to change our business requirements on the fly so to speak, but we are using the heaviest payload to send our data over the wire to our client.  If you aren’t familiar with why the strong-typed Datasets can have smaller payloads via web services over the wire then read this tip on strong-typed Datasets and web services.

Is the Data Really an Entity?

The above example didn’t favor very well for using an entity.  Why?  I think it has to do with the fact that the problem we were trying to solve didn’t match itself well to an entity.  I even question if the results from a search in this scenario is an entity.  I argue that it isn’t, it is a result set based on an action.  Not a true business entity.  If we think of the entity above as a Customer entity we would have a lot more properties within the Customer entity.  For example addresses, contact information, orders maybe and so on.  In our scenario we didn’t need any of that data to be filled.  As with most ORM mappers which help developers build entities, this is where a lot of them fall short in the fact that only a few properties need to be loaded, yet we have to pay the entity tax as I call it just to get to a few fields of data and load all the data within the entity. 

What if we created a brand new entity with just the four fields we needed to display?  While we could create a plain old collection of C# objects that only have the fields we need, we are still back to the problem of filtering, sorting, grouping and deployment. 

In this scenario:  Dataset 1  Entity 0

Another Scenario

To take our example a little further, what would we do if the end-user was able to double-click one of the rows that was returned from the search?  The end-user would then be presented with a new screen so they could edit the customer record and see other data like address information, contact information and so on.  What would we do in this case?

In this scenario we are truly dealing with an entity.  We are dealing with a Customer entity and it makes perfect sense to handle all of our bindings directly to a business entity.  Sure we have to bake in all of the OnChange events, validation, and so on, but the end result is we have a very flexible way of dealing with our Customer.  Maintaining customer information in just a Dataset scenario is slow, lots of overhead and isn’t near as clean as just a plain old C# object (or entity, however you think of it).  We can wrap our Customer entity with policy injection and validation much cleaner than we can trying to represent a Customer in a DataSet no matter how we look at it. 

In this scenario:  Dataset 1  Entity 1

Deadlines and Size of Application

When it comes to making a decision in your applications I say use common sense when it comes to what you are developing.  Honestly if I’m building a one or two page web form for internal use within our company, I’m cutting corners to get the thing done.  I want it to work and make the client happy but then move on.  Datasets here I come!  On larger applications though that isn’t the case.  For example if you are building a commercial web site or large scale enterprise app the code base will be taken more seriously.  There will be plenty of time to identify entities and put in the proper plumbing such as filtering, sorting, grouping, change tracking and more.  You may also take the time to explore one of the many entity frameworks available for .Net as well to give yourself a jump start. 

Conclusion

No matter how many times we argue the benefits and merits of one versus another I think the best approach a developer can take when it comes to Datasets vs the entity argument is take a holistic approach at the problem that he or she is trying to be solve.  Don’t forget to take into account future changes and how much maintenance may be required.  Use common sense and match the best solution to the problem.  I hope this helps and is now officially clear as mud.

 

Technorati tags: , , ,

Open Source to .Net Transition – Mac or PC?

Posted by Keith Elder | Posted in .Net, Linux, Open Source, PHP | Posted on 23-10-2007

2

It seems that an article I wrote a while back is making its way around the Internet once again.  It never fails that once a year or every 6 months it pokes it’s head up from the ashes, dusts itself off and finds new readers.  The article I’m talking about is this one:

How an Open Source Developer Transitioned to .Net

It is an interesting read and if you haven’t read it, check it out.

I started getting lots of emails from readers last night and this morning as the article was passed around.  One person emailed me a question that was particular interesting after reading it:

Thanks for sharing your story on your transition from .php to .net. My main question is; did you also change from working on Macs to the inferior PC’s?

Obviously by the reference of “inferior PC’s” in the question we know where this reader stands.  It is sort of like one of those interview questions you get that is completely loaded.  For example, “So Mr. Person Wanting a Job…. things around here are really busy.  A lot of the times you have to switch tasks very quickly.  How would it make you feel if you were working on a project and then your manager asked you to stop it and move onto something else?”  Obviously the question has already been answered.  Or rather loaded up for you to respond in the way the person asking the question wants to hear.  By the way, if you ask these type of interview questions, stop.  They get you no where.  I digress though. 

I don’t know if this question is the same loaded type of question but my first reaction was, wait, aren’t Macs made up of the same parts that are in PCs?  It is a hard drive, processor, video card and memory.  Apple looks at various vendors and plugs in the best deal / bang for the buck just like any other PC manufacturer.  Are PCs really inferior just because Apple has a better looking plastic cover than most PCs?  I don’t think so since they are essentially made up of the same parts.  Case in point I recently upgraded the wife from an aging iBook to a HP notebook.  I think she got a far superior product for a whole lot less money compared to a Mac.  That’s another post that I’m working on though. 

Maybe he was talking about the PC operating system being inferior?  What if I am running FreeBSD on my PC, does that make it more superior to the Mac since OS X is really just FreeBSD under-the-hood?  Or what if I’m running an Intel version of BEOS?  Maybe it was a OS X vs Windows comment?  The reader didn’t say so I am totally speculating on what he’s “really” trying to ask and also infer.

Here is the bottom line folks.  When you chose a technology you ultimately chose a platform.  We all do it and to say we don’t is just wrong.  When I was writing PHP/MySQL I used Linux for years since I thought it was important to develop applications on the same OS the application was going to run on the server.  I knew the Linux platform inside and out.  Even enough to teach it at the college level.  Today I write .Net code and I write that on Windows for Windows.  Again, I think it is important to write software on the same platform it is going to run on.  The difference is when you chose .Net you are married to the Windows platform, at least today.

Whether you want it to be or not, there is a huge platform investment made as a developer to understand the full potential of our applications.  I have a buddy at work that has been doing Windows IT infrastructure related stuff for years.  He understands a lot of things under the hood of Windows that I don’t even understand.  For me he is a resource I use often to pick his brain to solve a problem.  More times than not, he has an easier way to solve a problem than I was thinking just because he knows the platform.   For .Net development it means that those of us doing .Net development are married to the platform of Windows.  That is not a bad thing though since from a business standpoint the platform as a whole provides a lot of value.  

Yes, I use PCs today as opposed to Macs.  I’d be completely non-productive and probably lacking brain cells to development enterprise applications on a Mac and boot Visual Studio in a virtual machine.  I’d also be completely non-productive trying to write .Net code using Mono with VI.   I’ve seen lots of Macs at conferences and even friends of mine that are fellow MVPs have purchased Macs and run Visual Studio in a VM or just run Windows on the Mac 100% of the time because they like the Apple notebook better.   For those running Windows on an Apple, if you want to pay the Apple tax and spend a lot more money for your shiny toy fine, at least you understand that you are ultimately writing .Net on Windows.   For those that boot virtual machines and do .Net development God bless you, you must have the patience of Job.  I’ve done it and ultimately I came to the conclusion of:  Damn this slow and non-productive.  BTW, if you are a client of a consultant and he/she walks in with a Mac and is doing .Net development for you.  Run!  They just doubled your billable hours haha!  I poke fun in jest obviously but hey, it is something to think about if you are footing the bill no?

The thing is I still like OS X.  Notice I didn’t say Apple, because I don’t like the Apple hardware tax having built computers for years.  The operating system I like, nay, completely admire still to this day.  I’ve spent many hours looking at XCode on Mac OS X wishing it could be my development platform of choice.  Wishfully thinking that I could get a job as an Enterprise OS X developer at one time.  I wrote a few programs for Mac OS X and found it to be 5-10 steps and way more complicated than it needed to be just to do something simple like put a button on a form using Cocoa.  Compared to Visual Studio dragging and dropping a button onto a form and double clicking to wire up an event is apples and oranges (pun intended).  I’m sorry, but Apple spends all their time on making their OS shiny and adding features for end users but doesn’t do a damn thing to help developers embrace their platform at all.  At least that is how I see it.  If you don’t agree, then feel free to shine some light on my short sightedness, I’m all ears.

So yes, I use PCs today, not a Mac, and I don’t feel when I wake up in the morning and sit down at my computer I’m using an inferior product.  As a matter of fact I feel I have more options using the Windows Platform than I do using a Mac, especially since there isn’t an Apple store within 300 miles from me.  Not only that but professionally I have all sorts of nice haves that run and are supported with the Windows platform such as integrated authentication for applications, SQL Server, Biztalk, Windows Presentation Foundation, Winforms, Asp.Net, Windows Communication Foundation, Workflow Foundation, Silverlight, Visual Studio, Ado.Net, Windows Mobile, Office (Word, Powerpoint, Excel, Infopath, Publisher), Sharepoint, built-in analysis and data mining features, OLAP, Report Services and much more.  Based on all of that reader, which platform seems inferior now?

 

Bug in profileService Enumeration within System.Web.Extensions Web.Config file for Visual Studio 2008 Beta 2

Posted by Keith Elder | Posted in .Net | Posted on 04-10-2007

0

Kind of a weird title but it makes sense if you know what I’m talking about.  I was working through some final demos with Client Application Services for the code camp in Birmingham this weekend and found out that the enumeration within the <system.web.extensions> within the web.config file is misspelled. Here is what I’m talking about:

image

 

You can see when I typed out this property for the profile element I spelled it correctly, yet the Intellisense points to a different spelling.  I wouldn’t have caught it but I got a compile error and noticed there was a warning as well.  I looked at the warning and found the problem.  I filed a bug for it.  Feel free to vote on it here so this gets fixed:

https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=302725

Source Code for .Net Framework Released

Posted by Keith Elder | Posted in .Net | Posted on 03-10-2007

2

No the sky isn’t falling and it isn’t snowing in Mississippi but ScottGu, GM at Microsoft, just dropped a bombshell.  The title says it all, the source code for the .Net Framework will be released with the .Net 3.5 and Visual Studio 2008 release.

The source code will be released under the Microsoft Reference License and will include a lot of the base class libraries to start (System.IO, System.Collections, Asp.Net, Winforms, Ado.Net etc.   LINQ, WPF and other libraries will follow later.

What does this mean for developers?  Well it means that when you are debugging you can debug all the way down into the actual source to see what is going on.  Are you kidding me?  This is huge!  Huge I say!  This is a different Microsoft folks than we were use to in years past no doubt.  

What else would this mean?  I’m not sure, but it is a step in the right direction that is for sure.  This means the Mono project may not have to work as hard to figure out what the framework is really doing and the Reflector utility (a tool .Net devs use to view disassembled source code) will be made use of less.

Will the community be allowed to submit patches?  ScottGu didn’t discuss this and I’m not even sure how that would be accomplished (although I have some ideas, cough cough CodePlex).   

UPDATE:

For clarification, this isn’t “open source” it is just the source code is made available.  Notice I didn’t use the word open anywhere. In other words you can’t change it and recompile it.  You just have access to the source, but nonetheless, still very cool.