Saturday, February 17, 2007
NOVA / DC Area Code Camp
Wow, is this really my first blog post this year? The year has started off busy busy busy.
But enough about me... this is about you! YOU need to come to the NOVA Code Camp on 14 April! YOU need to volunteer to speak if you have some knowledge you are willing to share with your fellow developers.
I hope to see you there.
Details: http://novacodecamp.org/
Friday, November 10, 2006
DevConnections Vegas Slides and Demos
Another great conference complete. Around 5000 showed up and we had great feedback from the crowd that it was a good show. If you haven't been to connections before, you really should check it out.
I gave three talks this week. You can get the slides and demos for each below.
Real World ClickOnce: Slides Demos Workflow Driven Windows Applications: Slides Demos Implement a Data Layer with the VS 2005 DataSet Designer: Slides Demos
Thursday, January 5, 2006
Awarded MVP for another year! Visual Developer - Solution Architect
Looks like I get to hold onto the MVP title for another year. WooHoo!
Being an MVP has a lot of great benefits, but you need to contribute a lot of time to the community to earn the title. In case people are wondering the kinds of things you can do to qualify, I gave about 35 talks at major conferences in the last year, 14 user group talks, 3 webcasts, wrote a book (Data Binding with Windows Forms 2.0), published about a half dozen articles in various publications, helped run the Captial Area .NET User Group, and participated in 6 Microsoft partner events (SDRs, readiness events, etc.). This is all extra-curricular activity that does not directly earn me any significant money. On top of that I had to continue to earn a living as an architect and trainer with IDesign, which is a lot of fun in itself. Sounds exhausting, but I gotta say I feel pretty lucky to have found something that I love to do so much.
This year I have been moved to the Visual Developer - Solution Architect category instead of ASP.NET because that aligns more with where my primary focus is these days. I'm all about smart clients, but they don't have a category for that yet. I still can hold my own with ASP.NET, but just don't spend as much of my time in that space as with architecture and smart client technologies anymore.
Cool, cool, cool. I feel privileged to count myself part of a very talented community of Microsoft recognized experts!
Sunday, November 20, 2005
Interface-based Programming example employing the Factory pattern
When I demonstrate the use of interface-based programming in a class, I always give a demo of using interface-based programming combined with a factory pattern to add dynamic behaviors to an application. This is basically a scaled down version of what the provider model in ASP.NET 2.0 and the Enterprise Library do to allow you to externally configure components that will be called by the framework at runtime. ASP.NET actually uses abstract base classes instead of interfaces because they also provide some shared implementation, but the concepts are basically the same.
I use a simple little example of a client that defines an IDog interface (in a separate interface only assembly that it can share with component providers) that specifies the contract that providers are expected to implement. I then show how to build components separately that the client has no specific type information about, and load and invoke the behavior defined in those components dynamically through a factory and based on the interface definition that is the contract for how those components expose their behavior and some configuration file entries that the factory can use to load and instantiate the types. The client is able to do this without requiring any code modifications to accept new components, and can even have new behaviors added at runtime without needing to restart the application.
I have repacked the demo I normally give in class to:
Make it a little cleaner
Separate out the factory into a generic factory in a separate assembly that could be reused for any project
Use the new Settings features in the .NET 2.0 framework to enter the type information into a configuration file instead of using a separate XML file like I used to.
The factory method looks like the following:
public static T[] ConstructType<T>() where T : class
{
// Refresh the config cache in case the config file has been edited at runtime
Settings.Default.Reload();
// Load the collection of components from the string collection in config
StringCollection componentTypeInfoColl = Settings.Default.Components;
// Create a list to add the components to as they are created
List<T> components = new List<T>();
// Loop through the config strings trying to create instances of the appropriate type
foreach (string componentTypeInfo in componentTypeInfoColl)
{
try
{
// Config entries should be in the form:
// Fully.Qualified.TypeName, AssemblyName
// Split into its two parts
string[] typeInfo = componentTypeInfo.Split(',');
// Dynamic load the assembly
Assembly assem = Assembly.Load(typeInfo[1].Trim());
// Dynamic instance creation
T instance = assem.CreateInstance(typeInfo[0].Trim()) as T;
if (instance != null)
{
components.Add(instance);
}
}
catch { } // Just ignore invalid types
}
return components.ToArray();
}
So the only things you need to know to use this as a factory for other purposes than this demo is that it expects the type information to be entered in the client configuration file with an application settings section like the following:
<configuration>
<configSections>
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="DynamicFactoryLibrary.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>
</configSections>
<applicationSettings>
<DynamicFactoryLibrary.Properties.Settings>
<setting name="Components" serializeAs="Xml">
<value>
<ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<string>Animals.Dog, Animals</string>
<!--
<string>Animals.GermanShepherd, Animals</string>
<string>Animals2.Shitzu, Animals2</string>
-->
</ArrayOfString>
</value>
</setting>
</DynamicFactoryLibrary.Properties.Settings>
</applicationSettings>
</configuration>
I’m just using a StringCollection as the type for the component type collection, so each component that you want to add to the collection should be added to the section in the form:
<string>Animals.Dog, Animals</string>
You can see a couple of additional components commented out for dynamically adding them into the application (even while it is running). The type information uses a standard convention for specifying type information through a config file: specifically the fully qualified type name of the type, followed by a comma, followed by an Assembly name to load it from.
You can grab the whole sample here.
To demonstrate the example in action:
- First build the InterfaceBasedProgramming solution, which builds the interface contract assembly, the factory library, and the client application. The default client config file has all of the type information for available components commented out.
- Open the build output folder of the client (InterfaceBasedClient\bin\debug) and run the client by double clicking on InterfaceBasedClient.exe.
- Push the button and observe that you get nothing because no types have been provided or plugged in though the config file yet. Leave the client running.
- Next open the Animals solution, build it, and copy the build output (Animals.dll) from the bin\Debug folder into the client’s bin\Debug folder.
- Edit the InterfaceBasedClient.exe.config file through an editor, and uncomment the Dog type information as shown in the snippet of config file above, save the file.
- Hit the button in the client again, you should see a standard Dog Bark (through a message box).
- Edit the config file again, uncommenting the type information for a GermanShepherd (which is also defined in the Animals assembly), and save.
- Push the button again and you will see that type is dynamically used from the already loaded assembly.
- Go open the Animals2 solution and build it.
- Copy the Animals2.dll from its bin\Debug folder into the bin\Debug folder for the client.
- Edit the config file for the client again to uncomment the type information for the Shitzu type, and save.
- Click the button in the client again and you should see all three types of dogs bark.
Tuesday, November 8, 2005
Las Vegas Bound - Impressions of WCF
I'm catching a flight early tomorrow morning to Vegas for VS Connections and am really looking forward to it. VS Connections in particular, and DevConnections in general (the overall conference event) is well run, in great locations, and always has a lot of great content that I can benefit from as well.
I've been spending most of my recent prep time fine tuning the demos for my two WCF sessions, Build Event Driven Applications with Indigo and Connecting Smart Client Applications with Indigo. The more I work with Windows Communications Foundation (aka "Indigo"), I am struck by a number of things:
- I am impressed by how capable Indigo is.
- I am awed by how elegant and simple solutions are to complex aspects like security, transactions, queuing, callbacks, and so on.
- I am dumbfounded by how hard it is to figure out how to get to those elegant and simple solutions.
The last bullet is not really a criticism of what they have come up with, it is just the nature of the beast. I would draw on an analogy from my flying days to explain why this is so. Imagine the cockpit of a WW I fighter aircraft. You probably have half a dozen or less simple dials and gauges, and a stick and throttle. Imagine trying to use that set of controls on an aircraft that can fly at high subsonic speeds at high altitude carrying hundreds of passengers for 12 hour transoceanic flights. Not going to work too well. This is basically where you were at with past technologies to build complex, distributed, heterogenous, connected enterprise systems. It could be done, but the end result was not going to be pretty and it was going to take you a long time to get there.
Now with WCF, it is more like climbing into the cockpit of a 777. There is a technological elegance to everything that is there. But there are still hundreds (if not thousands) of individual switches, controls, displays, electronic gages and dials, menu driven control panels, etc. A great deal of human engineering has gone into everything that is in there so that for any given common task, there are only a couple of relevant controls that you have to touch and put into place to get the job done. The challenge is in knowing which one of those hundreds of knobs and dials to tweak.
The same is true for WCF. Microsoft has created an incredibly powerful and technologically advanced platform that is well adapted to building large distributed enterprise systems. In order to do that, there needs to be hundreds of switches and knobs that you can throw to address different scenarios. The downside to that is bullet number three above - you have to learn which switches and knobs are relevant for a given task, and in what order to throw them.
This is somewhat aggravated right now in that we are only at Beta 1 of WinFx (and its parts WCF, WPF, and WinWF), and the names, shapes, and locations of all the knobs and switches is constantly changing as they work on that human engineering task of trying to make it easier to use. Meanwhile the documentation and samples are seriously lagging, so working with it right now is a little like stepping into that 777 cockpit without any labels on the controls. When you say to yourself, "I just need transactions and certificate based security", it is kind of like saying "I just need to call the flight attendant at the second aft flight station". Simple to describe, but God help you in figuring out which switches and knobs to throw. At least there are not really any destructive ones that you can throw by accident. If you get it wrong, your app may not work, but you would have to go out of your way to write some code that would do bad things when WCF fails to let you communicate.
I'm looking forward to continuing to work with this technology and learn what all those knobs and buttons are for. Learning all the controls of the aft cockpit of the F-14 to run the weapons system, navigation systems, communications systems, and other tasks was one of the funnest things I have done in my life. The fact that we got to do that while strapped to a couple of 50K lb + of thrust zorching through the sky pulling G's and landing on the carrier certainly helped make it interesting. Sitting at a computer leaves a little to be desired in that department, but the learning challenge is still just as fun.
Monday, October 24, 2005
Upcoming DevConnections Talks
I'll be speaking at Visual Studio Connections (part of DevConnections) in Las Vegas from 5-8 November. This is a great and growing conference that happens twice annually in the US, usually Orlando in the spring and Las Vegas in the fall, that I have been privileged to speak at for the last couple years. If you haven't been to one yet, you ought to be hammering your boss for permisson/funding to attend for the following reasons:
- It will rapidly and time-effectively expose you to new solution technologies you might not get a chance to explore on your own
- You will get concentrated advanced training in current and future technologies, getting you up to speed on them in far less time than you can achieve on your own
- You will get presentations from the top speakers in the business
- You will get a chance to network with peers in the industry, learn from others experiences employing .NET technologies, which will make you more effective at employing them yourself
- You will have a lot of fun (OK, maybe don't tell your boss this...)
You can learn a lot peripherally from the conference too by reading the DevConnections blog here. There are posts from other speakers as they develop their talks and their own observations and experiences at the conference.
I'll be presenting the following sessions:
VSM356: Build Custom Data Bound Business Objects and Collections VSM351: Secure Smart Client ClickOnce Deployments VID306: Build Event-Driven Applications with Indigo VID309: Connect Smart Client Applications with Indigo
If you make it to the show (and you should!!), stop by and say hi!
Friday, September 23, 2005
Nice little SOA podcast
My associate Michele is part of a panel discussion podcast that Microsoft is doing on Service Oriented Architecture that will be ongoing over a period of time. The first one just hit the streets and is great. Check it out here.
Very nice little discussion of what matters.
.NET | Architecture  Friday, September 23, 2005 6:05:52 AM (GMT Daylight Time, UTC+01:00)  |
Tuesday, August 2, 2005
Advanced .NET Master Class Oct 17-21, Reston VA
I'll take the opportunity here for some shameless self-promotion...
If you are an intermediate to advanced developer who already has some .NET experience and are looking to take it to the next level, you might want to check out our Advanced .NET Master Class, which I will be teaching in Reston, VA from 17-21 Oct. This is a public offering of a high-demand course that we normally only offer onsite for larger development teams. You can find the full class description here. This will be a well-timed, comprehensive, in-depth coverage of developing enterprise applications in .NET 2.0. I cover a huge amount of material including advanced language features in C#, assemblies and versioning, serialization, multi-threading, transactions, security, Enterprise Services, and Remoting.
If you are interested, contact us through this link to obtain more information.
Friday, July 8, 2005
Wednesday, July 6, 2005
Wednesday, June 29, 2005
ClickOnce certificates in a nutshell
I have gotten a lot of questions surrounding the use of certificates in ClickOnce. Here are the key facts to understand:
- You must sign your ClickOnce manifests with an Authenticode certificate. VS 2005 will do this for you when you publish an application.
- Authenticode certificates are not the same thing as an SSL certificate or an X509 client certificate used for authentication purposes, even though they are all based on the same technology.
- You can generate your own certificate using Visual Studio, or the makecert command line utility. In this case, you are both the publisher represented by the certificate and the certificate issuing authority. You will sometimes see this referred to as a self-signed certificate.
- A third party issued certificate (i.e. Verisign, Thawte) is the preferred approach. These companies are already configured in Windows as trusted root certificate authorities (CA), and because they are third party verified, there is an additional level of implied trust associated with them.
- If you are part of a large enterprise domain and you have a domain CA, that CA can issue you a publisher cert for your domain that you can use, and your publisher certificate can be pushed out to client machines through group policy or SMS.
- If user prompting is acceptable for elevating privileges (based on the permissions requested by the application in its manifest and the permissions that would be granted by code access security based on the launch URL), then there is no need to install any certificates on the client side.
- If you want to avoid user prompting, you need to install your publisher certificate in the Trusted Publishers store on the client machine.
- At runtime, certificate checks are only done against the local certificate stores on the client machine. Specifically, the certificate used to sign the manifests is checked for in the Trusted Publishers store, and the issuer of that certificate is checked for in the Trusted Root Certificate Authorities store.
If you want more information on configuring certificates and how they work at runtime, you should check out my article on MSDN Online:
http://www.msdn.microsoft.com/library/en-us/dnwinforms/html/clickoncetrustpub.asp
Wednesday, June 22, 2005
Interview with Roy Osherove
Roy and I had a great long interview/discussion on a myriad of .NET topics back a couple of months, and he has it all edited and posted now. You can find it here.
Thursday, June 16, 2005
Sunday, June 5, 2005
Back in Conference Land at TechEd
I just got back from Holland Thursday after speaking at SDC there, and now I am in Orlando to speak at TechEd. These things are nothing but fun, but man, the travel can get crazy.
I had a great time last night joining in with the crowd at the Party with Palermo, which evolved from a loosely organized geek dinner into a great gathering of speakers, RDs, MVPs, and attendees in the Peabody hotel restaurant and bar. Today there are a collection of overlapping events that I plan to try to attend portions of, including some MVP events, the INETA summit, and some of the pre-con sessions.
The rest of the week is already pretty packed. My breakout session is not until Friday, but I have a bunch of other things I am participating in / presenting as well:
Tuesday 7 Jun:
3:15-6:15 PM- proctoring Juval Lowy's Instructor Led Lab (ILL) on Generics (DEV20/DEV20R)
9:00 - 10:00 PM - Preparing for Indigo Birds of a Feather (BoF) given by Juval
Wednesday 8 June:
8:30 AM-11:30 AM- proctoring Michele Leroux Bustamante's ILL on Iterators (DEV23/DEV23R)
7:00-11:00 PM Influencer Party
9:00-10:00PM Leading BoF session on Smart Client Deployment (BOF051)
Thursday 9 June:
3:15 - 6:15 PM - Giving System.Transactions ILL (DEV 22/22R)
Friday 10 June:
10:15 AM -12:00 PM - Answering Q&A questions through LiveMeeting for Juval Lowy's Simulcast session Being More Productive with the .NET Framework (DEV325)
1:00 - 2:15 PM - Presenting CLI440 Smart Client Offline Data Caching and Synchronization
Those are just the items that warrant an unchallenged block on my calendar. There are a ton of other events mixed in there as well to keep the week packed. I also need to get some more work done on my book this week getting the second half of the book up to date with Beta 2 and ready for Tech review, and also want to try to blog a few technical posts about stuff I am working on. Hmm, when is thattime expansion device going to be on the market??
Tuesday, May 31, 2005
Slides and Demos from SDC 2005 Netherlands
I gave 4 sessions at the Software Developers Conference 2005 in Arnhem, Netherlands yesterday and today. Great little conference and a lot of fun to get to speak at.
Here are the slides and demos from the sessions:
Smart Client Offline Data Caching and Synchronization: slides demos
Extending ASP.NET with Custom Handlers and Modules: slides demos
Smart Client Communications with the Middle Tier: slides demos
Tackle Complex Data Binding with Windows Forms 2.0: slides demos
Sunday, May 1, 2005
Tuesday, March 22, 2005
Sunday, March 20, 2005
Sunday, January 2, 2005
Comparing the IDesign process with Agile
Roy attended a week of our IDesign Advanced .NET Master Class last week, taught (and authored) by Juval Lowy, which includes a module on our recommended approach to software development process. Roy did a great job summarizing the key points in his article here, but seemed to have picked up a little too strong of a tone on certain points than was intended, based on my knowledge of the material (from being an instructor for the class myself) and from discussions with Juval.
Specifically, in the section of his article where he talks about the differences between our process and Agile, Roy talks about the ~30% effort dedicated to architecture and makes it sound like we are recommending a big-bang, all up front, try to think of everything to do with the product before doing any construction (aka waterfall), which is not what is intended. The ~30% effort dedicated to architecture and design is in fact done up front - but done up front for each stage of the product development, which distributes that effort fairly evenly across the product development lifecycle. It is one initial up front architecture piece, where you decide on the overall architecture of the system, what the major subsystems and components will be along with their interactions, security boundaries, transactions, identities, packaging, and so on, and then a bunch of smaller architecture and design pieces associated with the specific requirements for each component or subsystem in each stage of the development.
What we don't subscribe to is the concept that you can just sit down at a keyboard and start coding and come up with a coherent design for a large scale enterprise system as you go without some up front architecture and design work. We also believe that a majority of coders do not have the experience or big picture about the product for larger systems to be making all the design decisions themselves, thus the need for a dedicated architect who makes those architecture and design decisions throughout the development (with input from the team of course).
Another point I wanted to clarify is the use of test clients. I am not a true believer (yet) in full blown TDD, mainly because of the disconnect between our approach to actually doing some design and documentation before coding, at which point the benefit of writing tests before code becomes limited. But we definitely push that you should have tests for everything, preferably written in a way that you can automate the execution of those test, at a minimum the smoke test portion of them. Those test should be written and run by the developer, and can be used by QA for their testing as well. As such NUnit style tests are perfectly acceptable for component based testing of business logic and data access components, but some things really need a UI to test them, so for those we use simple UI test clients (typically WinForms). If you have not yet adopted NUnit testing and don't want to add that to your list of technologies to conquer, then you can write your tests how ever you like (such as all little WinForms and console test clients), but you should do so in a way that is not just total throw away.
Other than those minor points, I thought Roy's article did a great job of summarizing what I know Juval taught in the class.
Tuesday, December 28, 2004
Amen JayBaz!
JayBaz has a great little post regarding the compulsive obsession of many programmers about worrying about micro performance differences instead of writing clean code. Similar sentiments to my thoughts on Generics performance and performance in general.
Keep in mind this is a guy who used to be on the compiler team and REALLY knows the difference in performance of various statements down at the IL level.
(Depending on how soon you read this, you may not be able to get to the post - blogs.msdn.com is down right now. Thank you RSS + Newsgator :) )
.NET | Architecture  Tuesday, December 28, 2004 11:14:31 AM (GMT Standard Time, UTC+00:00)  |
Wednesday, November 17, 2004
Generics performance concerns? Don't sweat it!
Sahil points to the #2 bug report on the MSDN Product Feedback center regarding concerns over the performance of generics. My feelings on this pretty much echo an earlier post I made about performance in general.
Who cares if generics are 1000 or 10000 times slower (which I don’t believe – it might be for first call while the type is dynamically generated and compiled if necessary, but after that the difference should be small)? What matters is whether the performance of your application as a whole is sufficient and meets your specifications. People make this mistake all the time, worrying about the overhead of every instruction, when the real performance of whole applications is usually determined by network/file/database I/O or particular computational processes. That is where you worry about performance – at the places where you have identified through measurement that it needs to be addressed. Everywhere else, do what makes the most sense for maintainable code – and the type safety and reduction of repetitive code declarations provided by generics are huge from that perspective.
Bottom line is that even if it is 1000 times slower across the board , I don’t believe that will have a significant impact on the overall performance of most apps that will use generics. You also have to be very careful about making claims like this without substantiating them with actual measurements and the situations under which the measurement was performed. I bet I can set up a loop with a generic collection and an untyped collection of value types where the generic collection would beat the pants off the non-generic collection due to all the boxing/unboxing that has to occur getting those value types in and out through object references. Does that mean that generics are XX times faster than non-generics? No, it means that in one particular scenario (which is probably an immeasurable fraction of the overall computing time of the application) there is a measurable benefit of using one approach over another.
Bottom line: Generics have huge benefit. You should plan to use them anywhere you want type safety and don't want to reinvent the wheel. If you have implemented something with them and have MEASURED that to be a bottleneck for performance in your application, then optimize that code... possibly removing the generics. But please people don't start preaching that it is a “best practice“ not to use generics because of “performance“. Ugh.
Wednesday, November 10, 2004
Friday, September 17, 2004
Thursday, August 12, 2004
UIP MSDN Webcast demosPassing Arguments when starting a task in UIP
Version 2 of the UIP application block came out back in April, and included a lot of new functionality. Unfortunately, they also broke one important capability in moving from v1 to v2: the ability to pass in an set of initialization arguments to get a task initialized.
In V1, there was an overload of the UIPManager.StartTask method that allowed you to pass in an instance of a TaskArgumentsHolder object, which itself has a placeholder TaskArguments object reference where you could stuff anything you needed to pass downstream to the task that is being launched, such as user login info, command line or querystring params, etc.
This disappeared in V2 with the move to multiple navigation models. However, the fix is pretty straightforward to get that capability back - it just involves making a minor tweak to the UIP library source code, which is not a problem since you get full source code with the block.
Basically, what you need to do is go into the Navigators folder within the UIP project, and for each navigator type you want to support arguments on, you need to change the visibility of the StartTask method that takes a TaskArgumentsHolder parameter from private to either internal or public:
public void StartTask(TaskArgumentsHolder holder) { ... }
Then go into the UIPManager class, and add an overload for each of the StartXXTask methods that takes a nav graph name and a TaskArgumentsHolder, and have it call the appropriate StartTask on the appropriate navigator:
public static void StartNavigationTask(string navGraph, TaskArgumentsHolder holder)
{
GraphNavigator navigator = new GraphNavigator(navGraph);
navigator.StartTask(holder);
}
As soon as you do that, you are back in business. You can start a task and pass in arguments with something like this:
TaskArgumentsHolder holder = new TaskArgumentsHolder(Guid.Empty,null,"startupargs"); UIPManager.StartNavigationTask("StartupParams",holder);
That's all there is to it.
Saturday, June 26, 2004
Saturday, June 19, 2004
Tuesday, June 15, 2004
Thursday, May 27, 2004
Microsoft Application Block focus and evolution
I led a Birds of a Feather session last night on the Microsoft Application Blocks that was pretty well attended for being the last timeslot. Most of the people there had not yet used any of the blocks, so it ended up being more of a Q&A than a discussion, but it still went well and was a lot of fun.
Today I attended a session by Wojtek Kozaczynski from the Patterns and Practices team that puts out the blocks. Very good session on the future of the blocks that I wish I had attended before my BoF. They are working on something they are calling the Application Block Library that will be released towards the end of the year. This ties together a number of the existing blocks such as data access, exception management, configuration management, caching and more into a single library that is more consistent with the architecture and interdependencies of the blocks. They are also going to add some functionality to each, improve the documentation and samples to be more consistent and well formatted, and will include an administrative tool that will plug into Visual Studio 2003 and run as an external tool to ease the configuration and management of the blocks through their underlying configuration settings. All very cool stuff.
Bottom line message was to start using the blocks available today, don't wait for the library, but for apps that get started next year you will have a will have a whole new set of blocks to work with that will be even better.
Monday, May 24, 2004
Smart client track at TechEd
Just sat in on a great session by Tim Huckaby on Architecting and Building Smart Client apps in .NET. He showed a number of demos showing the differences between web apps (even rich ones with DHTML to enhance the user experience), auto-deployed smart clients with No Touch Deployment and the AppUpdater from gotdotnet, smart device apps, and Visual Studio Tools for Office apps. If you didn't make this one, check it out on the DVDs, Tim is always an awesome speaker.
Sunday evening I sat in on Juval Lowy's smart client Birds of a Feather session. Good lively discussion on the differences and justifications for moving to a smart client and what the comparative strengths and weaknesses are.
Right now in a session on handing occasionally disconnected client applications. keeping data stored and synchronized with the back end when you do connect.
We have been talking about the merits of smart clients for some time now and steering customers in that direction whenever it makes sense. It is great to see a focus on these topics emerging at TechEd.
Tuesday, May 18, 2004
ClickOnce - speaking at Bay.NET on Wed
If you are interested in learning about the future of auto-deployment of smart client applications with .NET, specifically ClickOnce (a new deployment technology in .NET 2.0), and you are in the bay area, come check out my talk this Wed night at the Bay.NET user group meeting. (www.baynetug.org).
Sunday, May 16, 2004
Windows Authentication and Authorization using Forms Auth in ASP.NET with Enterprise Services
I put together a custom authentication and authorization solution this week for a customer that I wanted to share, both because it works pretty well, and also to see if anyone can spot any gaping security holes in the approach that I didn't think of before we go prime time with it. It is basically a way to mix ASP.NET Forms Authentication with Windows Authentication and Authorization without requiring elevated privilege on the ASPNET worker process account. The solution involves using an .NET Enterprise Service (COM+) component to do the actual checks against the Windows accounts.
The scenario is this. The customer has an ASP.NET web application with some unique requirements regarding authentication and authorization. They need explicit control over the login/logout process because they need to restrict session length and number of concurrent logins for some accounts differently than others. They require that the accounts being used for auth be Windows accounts, and that the auth decisions are based on the Windows users and groups. They are also running on Win2K server. They also need to support Linux clients running Mozilla. At least they made it an easy scenario <g>.
The need for the accounts to be Windows based makes Windows auth sound like the ticket, but there was no way to satisfy the login/logout/session/concurrent login limitations in the requirements because your code is pretty much out of the loop with the built in Windows auth, so Forms auth sounds good. But then you have to use Windows account information for the actual auth decisions. Fine, that is what the LogonUser API is for.
Ah yes, but then there is that little hitch that they are running on Win2K, which requires the SE_TCB_NAME (Act as part of operating system) privilege to call LogonUser, which is not something you want to give to the ASPNET account if you want a secure system. So what to do...?
What I came up with was to create a .NET Enterprise Services component that runs in a Server application. The application is configured to run under a special Windows account that is just a normal user, but has the required SE_TCB_NAME privilege assigned to be able to call LogonUser. The account is also configured so that interactive logins are disallowed. The component exposes an Authenticate method that takes the credentials and returns a bool indicating success or failure, and returns the token that LogonUser gives you to represent the user.
The ASP.NET app includes a custom principal class that encapsulates the user identity provided by the login process through Forms authentication, and also holds onto the user token returned after calling Authenticate on the ES component. I tried using the token directly within the ASP.NET app to create a WindowsIndentity, but could not get it to work because of the token coming from another process. So I added an IsInRole method to the ES component that takes the desired role name and the user token. This method uses the token to create a WindowsIdentity and WindowsPrincipal, and calls IsInRole against that. The IsInRole method of the custom principal just calls that corresponding method in the ES component, passing in the role and the user token it cached after calling Authenticate. The user token is also stored in session so that it can be used to recreate and set the custom principal on subsequent requests.
Using this approach, the login form just calls Authenticate, and if successful, stores the user token in session and uses FormsAuthentication to issue the login session cookie. In the PreRequestHandlerExecute event handler in the application class, the custom principal is recreated and set as the principal on the context as long as the request is authenticated (managed by Forms auth). Then the rest of the app can just call IsInRole on the User property like normal, and the custom principal's implementation of that gets called. This is also the place where all the unique session length/concurrent sessions are enforced.
Obviously going cross process on every request for role checks is not such a great idea, so we also cache the authenticated roles after they have been checked once through the ES component, and time out that cache using a configurable period so that if someone's group membership has been changed and they are running a long session (the app has a self-refresh status page), those changes will be picked up.
To add some additional security, we use COM+ role based security to make it so that only the local machine ASPNET account can call into the component.
It may sound a little complicated, and it was to get it all implemented and working correctly the first time. But it has the advantage that it is very easy for the ASP.NET app to integrate, makes the custom mechanisms being used transparent to the app other than the call to Authenticate and the call to attach the custom principal. And the security provided by ES gives a way to get the privileged role out of the ASPNET process. We could have used a Windows Service to do this as well, but then we would need to call into the service somehow and protect against unauthorized callers, and all that is built into ES.
Anyone see any holes here? Was there a better way to do this that escaped me?
.NET | Architecture  Sunday, May 16, 2004 5:40:45 PM (GMT Daylight Time, UTC+01:00)  |
Friday, May 14, 2004
COM+/Enterprise Service Components are not a legacy technology
I am a firm believer in the use of component based development, and for the middle tier, Enterprise Services is the right way to go for most serious applications. Unfortunately there are a lot of misconceptions about the positioning of Enterprise Services, aka Serviced Components, aka COM+ with respect to .NET development. The biggest of these is viewing COM+ development with .NET as a legacy approach. Another is that when you build COM+ components with .NET, you are doing COM interop. Another is that COM+ is too hard to be worth it. All of these are just wrong.
To really get things in perspective, you have to think of COM+ as what it really is - component services provided by the operating system. In the same way that you use the OS for services such as file and network I/O and access control, when you use COM+, you are really just using component services provided by the OS. So doing COM+ in .NET is no more “legacy” than doing file I/O or network calls using .NET. In fact it is much less so because the level of abstraction and architecture provided by COM+ is far more advanced than those other services provided by the OS. When Microsoft put together COM+, they put together a very forward looking architecture for building robust, scalable, high performance applications.
Building Enterprise Service components is also the best thing you could be doing today to migrate to Indigo tomorrow. Most of the hype surrounding Indigo (and well, just about everything in the last couple years) is about Web Services. And yes, one of the primary scenarios for using Indigo will be to build service oriented applications that happen to communicate using web service protocols. But the thing is that the Indigo programming model abstracts away all the web service goo from you and lets you work with a much more clean and declarative model. It happens to have a declarative model that looks much closer to Enterprise Services programming today than it does to web services programming today. Through configuration, you will be able to control the transport layer and make it act like a web service, Enterprise Services, or .NET REmoting under the covers, but your code will look an awful lot like ES code from what I have seen.
So ES is not legacy by any stretch, it is very current and powerful in its capabilities, and it is very forward looking in terms of what you will build in the future.
What about interop? Well, certainly if you are calling out to a legacy COM component that is running in COM+, you are doing COM interop. But if you build a .NET ES based system, the .NET components do not use COM interop to talk to one another. There is some unmanaged code in the loop for providing those component services from the operating system such as distributed transactions, security, instance management, queuing, loosely coupled events and so on. But there is unmanaged code involved for many other things your apps do that reach outside of their own context, so you shouldn't let that fact drive your thinking about ES. Bottom line is that you need to try things and see if the technology can provide the performance needed for your application, not just blindly avoid things that you perceive to have performance penalties. And the fact is that you can get some huge performance benefits from the instance management features of COM+ and from the speed of the underlying transport if you design your system well.
Finally there is the difficulty of building ES systems. And yes, this is not the kind of technology that your average community college philosophy major can use to throw together a toy app in an afternoon. You have to design your system, consider the communications and calls between components, figure out which services you need to use and how to best use them, and you have to have a lot of discipline and automation in your development and build process to do it right. But the benefits of doing these things are huge on their own and are something you should be doing for critical business applications in the first place, whether you use ES or technology X.
You also have to consider the time/cost payback of using ready-to-use, well tested and proven technology for services like distributed transactions, authentication and authorization at the application, component, interface, and method level, object pooling, just in time activation, queued component method calls, etc. etc. Sure you can build your own mechanisms for these things, but are you really so vain as to think you can build it better than they did? And without spending orders of magnitude more time than it would take to use the services out of the box? Need 2, 10, or a 100 components that call each other, possibly touching many different databases, to all become part of one distributed transaction? Sure thing, just slap an attribute on each class and each public method and you are done with ES. How long would it take you to get this right managing the transactions yourself? A little longer methinks. A security mechanism that can be locked down by the developer with a few attributes at design time based on the spec, but that can be easily modified later on adminstratively if requirements change? Done with ES. Spin your own? Have fun. Dispatch method calls asynchronously through MSMQ to components that you may not even have network access to at the time you execute? Sure thing, with ES a couple attribute, a slightly different instance creation coding pattern, done. Spin your own? Have fun.
Bottom line, people need to get past the fear and misconceptions of Enterprise Service components. If you are building toy apps, go ahead and ignore ES and keep building monolithic or client-server apps that don't scale and are hard to maintain. But if you are building serious business apps for the middle tier and might need any of the services mentioned, then you should be looking at ES as one of your first choices. ES is an incredibly powerful capability that too many companies dismiss out of hand.
If you want to learn more, first, pick up a copy of Juval's book. A strategic .NET-only developer will read every chapter for the concepts and understanding of each of the COM+ services, but will not get wrapped up in the C++ code presented. They will then cross reference the appropriate portion of Chapter 10, which presents just how to use each service with Enterprise Services in .NET.
Also, check out our IDesign Method, which is one of our service offerings for helping companies architect and design their ES systems.
Saturday, May 8, 2004
Address perf WHERE IT IS NEEDED
I sat in a talk recently on performance with .NET applications. The speaker was suggesting things that I here others say often but I strongly disagree with. Two specific issues were the recommendation to use ngen and to never include debug info in release builds to achieve the best performance. The conversation went something like this:
I pressed him on the ngen:
Me: I thought one of the reasons you shouldn’t ngen is because the JIT compiler can do optimizations that result in superior runtime performance over ngen?
Him: Well, yes that is true
Me: So if you really care about perf, you shouldn’t ngen?
Him: Yes, but if you ngen you dramatically improve the start up time for the app
Me For the first time the app is run only, right?
Him: Well, yeah….
Me: And, there are load time effects that ngen can have (rebasing) that can actually result in worse load time perf?
Him: Well, yeah…
Then the debug info in release mode:
Him: You should definitely avoid putting debug info in your release builds
Me: So what is the impact if you do?
Him: Well, a couple extra instructions per method call
Me: So do you think an extra couple instructions actually has an impact on the overall perf of most apps? Aren’t they usually IO bound or have other perf bottlenecks that really form the performance limit for most apps?
Him: Well, yeah…
Why don’t people get this? I'm not saying you shouldn't always consider perf or that you should do stupid things that will affect perf. But if you are doing things that affect the maintainability of your system, I would always favor doing the things that result in more maintainable systems. Then address perf where needed. If your performance is already adequate, then you don't have a problem. If it is not, it is probably due to one or a couple hot spots in your application that you can do some optimization on to get things back in check.
Ngen can either help or hurt perf, and can result in unpredictable results if anything in your system changes with respect to what version gets used. Me, I like deterministic systems. Debug info in your release builds can give you additional insight when errors happen in the production environment including line numbers in exceptions and additional ways to debug.
A lot of it has to do with good architecture and design too. Most often people apply performance tweaks liberally because they have no idea where the hot spots might be in their app or how to find them.
I just get frustrated when people latch onto a concept and apply it blindly without understanding when/where it is actually needed. Let's face it, if a couple extra instructions per method call is really driving the performance of your entire application, you either write some incredibly tight code, or your app is a simple little test app that you created to drive home your point that doesn't go out and make any DB queries, network calls, access the disk, or any of the other things that really drive the perf of real world apps.
.NET | Architecture  Saturday, May 8, 2004 3:32:20 PM (GMT Daylight Time, UTC+01:00)  |
Sunday, April 4, 2004
TDD in the real world... for real?
I like Test Driven Development (TDD). It makes sense to me at a conceptual level, it feels right, and it basically formalizes a number of practices I have had for years (but without the discipline to necessarily do it the same way all the time). I think it leads to better software both through finding defects earlier and because it changes the way you approach coding in a good way that makes you think about the client API very closely up front (because your tests are client code).
The one thing I don't like or really just haven't gotten my arms around yet is how to really apply it comprehensively across all the kinds of development I do. For business objects that encapsulate some data and expose operations on that data, TDD is perfect and easy to understand. For things like asynchronous, event-driven services and interactive UI code, I still have a hard time figuring out how to apply TDD.
So when I finally got around to reading the latest MSDN, I was looking forward to the article in there on TDD. I found the article to be well written and thought it did a great job explaining the basics and how to put together TDD test fixtures in .NET and work with NUnit. I was a little dissatisfied with the finish though.
As I read, I started salivating as I got to the section titled “Using TDD in the Real World”. Cool, someone is finally going to go beyond talking about money classes as demonstrate using TDD for something hard... or maybe not. Then it started talking about addressing GUI testing, even better... or maybe not. In the end, the “real world” scenario ended up being a combo box driven by a simple data container class for countries, and the only thing that TDD was demonstrated against was the country list class. Hardly a real world scenario, and how you might test the combo box that uses it was quickly slipped around.
Does anyone out there have any good resource links to using TDD for GUI and/or asynchronous/event-driven scenarios? That is the one area I still need a better clue, but I can't seem to find any good examples or discussion of them.
Wednesday, March 17, 2004
Prefer XPathNavigator
I spoke last night at the Central Pennsylvania Users Group in Harrisburg, PA. They have a great group and about 35 folks turned out despite snow and nasty weather. Judy Calla is the group lead and gave a nice little beginners talk on debugging and error handling in .NET applications. I then jumped in with a talk on querying XML data in .NET.
One of the key points I always try to draw out in that talk is to get people familiar with the XPathNavigator model and the differences between the various types of XML documents in .NET (XmlDocument, XmlDataDocument, XPathDocument).
It is a natural fit for people who have worked with MSXML before to settle in and use the XmlDocument class (the W3C DOM implementation in .NET), never going beyond the methods and properties exposed by XmlNode and its derived classes to do their work.
However, I try to get people familiar with the fact that the preferred model for working with XML data in memory in .NET is working through the XPathNavigator, since it can be used across all three of the document types, and especially since it will take on an even more significant role in .NET 2.0 with the introduction of the modifiable XPathDocument. More on that in a minute. I also point out that you can layer an XPathNavigator implementation on top of any hierarchical data that you control, giving it an XML like working model, even though it may have nothing to do with XML itself.
The XPathNavigator base class ( and the concrete implementations provided by each of the document types) provides a consistent and clean model for navigating and querying XML data. To get one, you just call CreateNavigator on the underlying document instance. What you get back is effectively a cursor into the document nodes that you can move around with the various MoveXXX methods, or you can query the current node and all sub-nodes with XPath expressions. When you query through this model, you have the choice of just passing an XPath expression as a string to the Select or Evaluate method (the former returns a node set result, the latter returns a value result - bool, number, string - if that is what the XPath expression is expected to evaluate to), or you can pre-compile the expression for faster execution if the query will be made more than once.
The XPathDocument class in .NET 1.X is a lighterweight object model than the one in the XmlDocument class and will have less of a footprint in memory for the same XML document in most cases. The big decision point in which of those two document types to pick currently is whether you need write access to the nodes you are dealing with. If the answer is yes, you only have one choice currently, and that is to work with the XmlDocument class. You can and still should do so through an XPathNavigator, but the underlying nodes are still XmlNodes instead of XPathNodes, and are therefore write access. If you are just looking to query and navigate the data to perform processing, then XPathDocument is the better choice because of the lighter weight object model.
In .NET 2.0, the big thing to be aware of is that the XPathDocument class becomes read/write. But more important than that is that any changes you make to the document (modifying, inserting, or deleting nodes) are tracked by the document in a similar fashion to the way the DataSet tracks changes. This means that you can then use the XPathDocument to perform updates to the underlying data store from whence it came. That is huge.
So bottom line, if you are not using XPathNavigator today for working with your XML documents in .NET, you should be. Look into and get used to the model. It will give you better consistency and a migration path to move you XML document processing code from the DOM today to the XPathDocument in .NET 2.0 with minimal changes.
Saturday, February 14, 2004
A Day in the land of Oracle
I'm working on a project for a customer that I have mentioned before that is a Java web app using Oracle products. I know, what is a .NET guy doing this for? Trust me, I have tried hard to persuade the customer's customer that they would be better off with a .NET solution to no avail. They dictated an Oracle/Solaris architecture before the project even started to maintain platform homogeneity within their network, so we are stuck with that.
We are just getting started into the design phase (yes, a waterfall process also dictated by the customer... do these people never learn??), and trying to nail down the technologies and software architecture we will use given the constrained enviroment. It is like trying to learn a foriegn language in some ways. The basic architectural concepts are the same, but the terminology, libraries, technologies you use to achieve it are all very different.
The other thing that is weird is the low community support structure in the Oracle world. After much searching of the Oracle Tech Net and the web in general, it was just really hard to find good articles and how-to type information on web app architecture and design with Oracle. Basically, I just needed to talk to someone who does what I do with .NET but does it with Oracle products so that I could get them to help me draw the parallels. We were sent one after another consultant by Oracle, telling them we needed a web application architect each time, and ending up with DBA after DBA after DBA, each basically saying “I think you can write all your HTML in PL/SQL”. Yeah, a 1 tier app, that's just what I had in mind. Either that or we ended up with the Technical Manager type who could rattle off a laundry list of options (most involving obscene licensing costs), but couldn't really guide us on the right selection of technologies given our requirements and expertise.
Finallly yesterday we went to the Reston Oracle headquarters and met with some folks and got the guy we needed. I could immediately tell that he spoke the lingo, even though he was talking different tools and terms, we were both describing the same app architecture and he was able in about an hour's time to get us right on track.
Some of the stuff in the Oracle suite (JDeveloper in particular) are pretty nice. Microsoft should take a look. Even though their Business Components for Java (BC4J) framework and Struts (an MVC open source framework) are heavily driven by XML, you almost never have to touch the raw XML yourself. They have wizards and dialogs that encapsulate ever setting you might possibly need to make in the XML configuration files of many flavors. We need more of that in .NET, and I think some is coming in Whidbey from what I have seen and heard.
It is definitely a more DB centric world that we are used to in the .NET realm, but I could see where that pendulum might swing closer to the Oracle approach with some of the features coming in Yukon.
Thursday, January 22, 2004
XmlSerialization and Interface Based Programming
Check out the code below and see if you can see spot what is wrong with it:
public interface IChildObject { string Name {get;set;} }
public interface IContainerObject { IChildObject Child {get;set;} void Save(string fileName); }
public class ChildObj : IChildObject { private string m_name = "Fred"; public string Name { get { return m_name; } set { m_name = value; } } }
public class ContainerObj : IContainerObject { private ChildObj m_child = new ChildObj(); public void Save(string fileName) { XmlSerializer xs = new XmlSerializer(typeof(ContainerObj)); FileStream fs = File.OpenWrite(fileName); xs.Serialize(fs,this); }
public IChildObject Child { get { return m_child; } set { m_child = value as ChildObj; } } }
This was one of those subtle little things that was confounding a customer new to .NET, but the not so descriptive exception made it a little easier to figure out once I saw it:
InvalidOperationException: There was an error reflecting the type ContainerObj.
The issue of course is that XmlSerialization uses reflection to figure out what to write out. It probes the type and gets all its public fields and properties and writes those out with serialize or reads them in with deserialize. Because the container object exposed its child property as an interface type instead of the implementation type, the reflection stopped there and choked and it can't XML Serialize this type.
If it is already using reflection, why couldn't it have been coded to use reflection a little harder and determine the underlying type for any interface properties? There are a lot of situations it would be good to expose the property as an interface instead of a concrete type, but if you do that, you can no longer benefit from the simple XML serialization mechanism. I hate to have to violate good interface-based design just to take advantage of XML Serialization, but it seems like that is the only choice here.
I realize we could use normal .NET serialization (binary or SOAP), but XmlSerialization was ideal for the task at hand.
Hopefully the changes they are making to XML Serialization for Indigo will make this scenario OK.
Am I missing anything obvious?
.NET | Architecture  Thursday, January 22, 2004 1:54:06 AM (GMT Standard Time, UTC+00:00)  |
Friday, January 9, 2004
Microsoft Application Blocks Article up on asp.netPRO site
My article on the Microsoft Application Blocks is now live on the asp.netPRO site. Unfortunately for some, you have to be a subscriber to access it. It will be in the next print mag that comes out as well.
The article covers the blocks at a high level, then drills down into the DAAB and the UIP blocks. I have other articles on the site for the CMAB block and have one on the EMAB coming out soon online as well. These latter two are not locked to subscribers only.
.NET | Architecture  Friday, January 9, 2004 6:32:22 PM (GMT Standard Time, UTC+00:00)  |
Tuesday, January 6, 2004
Done taping .NET Rocks!
Carl Franklin was kind enough to invite me to interview on .NET Rocks! and we just finished taping. I was a little nervous knowing the size the show's audience has grown to, being a dedicated listener myself. But Carl is a master at doing these things and just made it feel like a good techie geek conversation between friends.
We focused mainly on ClickOnce, which is one of the things I have been spending most of my time focusing on in Whidbey, and covered all the things that make ClickOnce a great thing. I also got to brag a little on what I used to do, and put a plug in for my book.
You just can't buy good publicity like that. Unless I sucked....? :P
Should be up on the site in a few weeks.
Thanks Carl!!
.NET | Architecture  Tuesday, January 6, 2004 8:25:08 PM (GMT Standard Time, UTC+00:00)  |
Tuesday, December 9, 2003
Oops I did it again... Service != SOA
While reflecting on yesterday's post on SOA, I realized I fell into the same old trap again that many are guilty of - blurring the distinction between Services and SOA. Most of what I was talking about in that post was really comparing Services to components or objects, not comparing SOA to component oriented or object oriented development. SOA is really about how you design and build systems composed of services, not about what a service is. I have fell into this trap a number of times, because talking about SOA inevitably leads to first defining what a service is and how it relates to components and objects, which is basically where my post left off. SOA is a much bigger beast, and I have to agree with Sam's post that it does lead to different methodologies at the high level architecture and design level. But at some point in that process, you have to build a service or services, and at that point you generally start to step right back into the comfortable world of component and object based development.
Sunday, December 7, 2003
SOA != Death of components and OOP
SOA != Death of components and OOP
Sam is trying to get his head around SOA, along with many of us. He states:
“I must confess SOA to be one of those paradigm shifts - it really does mean the death of objects at least as we know them.”
I don't see it that way at all, any more than the development of component-oriented development meant the death of OOP. I see SOA as a semi-formalization of a higher level of abstraction that is needed in large scale applications. OOP developed as a good abstraction and way of encapsulting state and behavior in small-grained pieces of code for maintainability and (*potential*) reuse. Components evolved to encapsulate meduim grained chunks of functionality at a level where you could start to compose systems from pieces that could be more easily understood, managed, maintained, and yes, sometimes reused. I see SOA as a further evolution down that path - encapsulating functionality and processes at a course grained level - making it easier to describe and compose larger systems out of collaborating, interrelated parts.
I don't think SOA means the death of OOP or Components at all. Just like most people build components using OOP, I think most people will built SOAs using OOP and Components. They are not competing concepts but complementary.
Indigo gets into the game by not forcing you to choose up front in and all or nothing fashion about which particular communication technology is going to be used to let services collaborate by using the abstraction of SOA. If you have two pieces of a system, or two systems that need to communicate and share information, focus on the communication contract, not the implementation mechanism. Maybe for now they are both going to be sitting on the same machine, but you want strong security and have more than one resource manager - a good fit for Enterprise Services. Next year you find you need to scale out or relocate those services and now there is a firewall in between. Now Web Services start to make more sense. Today you would need a significant rewrite of the application. With Indigo it would mostly be tweaking configuration.
I spent a lot of time looking at, writing on, and speaking about the Microsoft Application Blocks before attending a workshop on Indigo in Redmond back in September, and it helped me understand Indigo in a big way. Many of the application blocks use abstractions of Providers and Publishers that can be configured and plugged in to change the behavior of the block without needing to change any of the application code. This is done by adding classes (components really) that implement the interfaces that constitute the contract of the block, and using config files to get them loaded dynamically at runtime. The application just programs against the interface, so it doesn't care which provider or publisher is servicing the functionality. They are very slick.
The Shadowfax project Sam mentions is another block in development addressing SOA.
With SOA, the contract just migrates from being a binary interface specification to being a more abstract and platform neutral WSDL specification. How you satisfy that contract depends on the requirements of your application.
Bottom line, I see SOA building on OOP and Components conceptually, and see SOA applications being built with OOP and components. I hope people don't decide that this means they should go back to procedural programming.
|








| May, 2013 (1) |
| April, 2013 (2) |
| March, 2013 (2) |
| February, 2013 (2) |
| January, 2013 (2) |
| December, 2012 (3) |
| November, 2012 (1) |
| October, 2012 (1) |
| August, 2012 (2) |
| June, 2012 (2) |
| May, 2012 (3) |
| April, 2012 (1) |
| March, 2012 (2) |
| February, 2012 (2) |
| January, 2012 (1) |
| November, 2011 (4) |
| October, 2011 (1) |
| September, 2011 (2) |
| August, 2011 (1) |
| July, 2011 (1) |
| May, 2011 (5) |
| March, 2011 (4) |
| February, 2011 (2) |
| January, 2011 (3) |
| November, 2010 (4) |
| October, 2010 (1) |
| September, 2010 (5) |
| August, 2010 (5) |
| July, 2010 (6) |
| June, 2010 (8) |
| May, 2010 (2) |
| April, 2010 (2) |
| January, 2010 (1) |
| December, 2009 (3) |
| November, 2009 (2) |
| October, 2009 (3) |
| September, 2009 (3) |
| August, 2009 (2) |
| July, 2009 (3) |
| May, 2009 (3) |
| April, 2009 (2) |
| March, 2009 (1) |
| February, 2009 (2) |
| January, 2009 (2) |
| December, 2008 (1) |
| November, 2008 (2) |
| October, 2008 (5) |
| September, 2008 (4) |
| August, 2008 (2) |
| July, 2008 (1) |
| June, 2008 (2) |
| May, 2008 (2) |
| April, 2008 (3) |
| February, 2008 (6) |
| January, 2008 (3) |
| December, 2007 (1) |
| November, 2007 (1) |
| October, 2007 (5) |
| September, 2007 (1) |
| July, 2007 (3) |
| June, 2007 (8) |
| April, 2007 (2) |
| March, 2007 (4) |
| February, 2007 (1) |
| December, 2006 (2) |
| November, 2006 (9) |
| October, 2006 (5) |
| September, 2006 (3) |
| August, 2006 (2) |
| July, 2006 (4) |
| June, 2006 (5) |
| May, 2006 (10) |
| April, 2006 (4) |
| March, 2006 (2) |
| February, 2006 (12) |
| January, 2006 (7) |
| December, 2005 (2) |
| November, 2005 (15) |
| October, 2005 (6) |
| September, 2005 (7) |
| August, 2005 (3) |
| July, 2005 (10) |
| June, 2005 (11) |
| May, 2005 (7) |
| April, 2005 (8) |
| March, 2005 (6) |
| February, 2005 (2) |
| January, 2005 (6) |
| December, 2004 (3) |
| November, 2004 (5) |
| October, 2004 (2) |
| September, 2004 (5) |
| August, 2004 (13) |
| July, 2004 (6) |
| June, 2004 (14) |
| May, 2004 (17) |
| April, 2004 (12) |
| March, 2004 (8) |
| February, 2004 (10) |
| January, 2004 (14) |
| December, 2003 (9) |
| November, 2003 (13) |
| October, 2003 (3) |
Sign In
|