A big topic these days is about "Discoverability" and the .Net framework. Developers talk about how big the .Net framework has become with 2.0, 3.0 and now 3.5 frameworks. There a several ways to discover capabilities of a framework. One way is word of mouth via blogs or developers you work with. Another is just searching through MSDN and Google. Finally, there is the Visual Studio object browser and of course Reflector. Last year when I was developing search solutions for both WSS and MOSS I realized that the SharePoint 2007 object model had expanded and changed. This was at a time when there was little or no documentation. Even now the documentation for the SharePoint 2007 object model leaves a lot to be desired. Since SharePoint 2003 I have used a "Discovery" tool named ClassMaster (http://www.certdev.com). This tool has enabled me to dive deep into the SharePoint object model and understand how to use SharePoint to its fullest extent.
One of the biggest benefits of this tool is being able to see the object model at runtime without having to write any code. I load an assembly, enable the option to view private and internal types. I then select a method and constructor, fill in the arguments and execute. I can now see the object in an enhanced property grid which displays all the properties of the object including private and internal fields. This is useful because now I can navigate into private objects that are being used. Visual Studio's debugger does not give me this. For instance, the SPSite class has a private field for holding the SPConfigurationDatabase object. With ClassMaster I can click on the button next to this property and view all the properties for the SPConfigurationDatabase. From here I can now view the ObjectCache property of the SPConfigurationDatabase and view all the objects that are cached by SharePoint. The tool helps me see the dependencies in the object model during runtime.
Using ClassMaster during SharePoint 2007 Development
When ever I am doing new development in SharePoint I use ClassMaster to determine if there is an existing class that I can use to perform a task. For instance, when I was trying to figure out how to obtain the start addresses that the MOSS crawler uses to crawl content. I started browsing the Microsoft.Office.Server.Search assembly. I found the StartAddressCollection. It is a public sealed class with an internal constructor that takes a ContentSource object. I right clicked on the StartAddressCollection and went directly to MSDN to see what it had to say. Of course there is nothing about the constructor since it is internal. So I looked at the ContentSource class and noticed it has a StartAddresses property. So now I know I need to create a ContentSource object to get the StartAdressCollection. However, the ContentSource object is an abstract class which means it has to be inherited. However, the ContentSource class has a "Parent" property which holds a ContentSourceCollection object.
So I navigate to ContentSourceCollection. I look at its internal constructors and see it can only be created with a Content object. Next step was to navigate to the Content class. I then see it can only be created with a SearchContext object. Looking at the SearchContext class I then discover that is has a static property called "Current" which returns the current SearchContext. I right click and execute and it returns nothing. So I right click and search MSDN. This property returns the SearchContext for the current request. Which means this only works when running in a asp.net worker process. So I look at other methods on the SearchContext class and notice the overloaded static method GetContext which takes either an SPSite, ServerContext, or a string representing the search application name. I look at the Microsoft.Office.Server.ServerContext class and see it has a static default property which returns the default ServerContext. So, from this discovery process I determined I could do this to get to the start addresses.
SearchContext = Context.GetContext(ServerContext.Default);
Content con = new Content(SearchContext);
StartAddressCollection sac = con.ContentSources.StartAddresses;
Steps to prove this in ClassMaster
- Right click on the ServerContext.Default property and click execute.
- Save the ServerContext object to the built-in clipboard.
- Navigate to the Content class and select the constructor.
- Double click the row header in the constructor parameters grid which opens an input dialog.
- Click the clipboard icon and select the ServerContext object previously created and click OK.
- Right click the Content class and execute.
The results now show a Content object. In the property grid I could click on the ContentSources collection which brought up a ContentSource collection editor. I then selected the ContentSource I was interested in and clicked on the StartAddresses collection which displays all the Uri objects representing the start addresses that the MOSS crawler uses. Now I know what I need to code and I know it will give me exactly what I need.
I use ClassMaster also as a unit testing tool when designing new components. I include it with my software testing regimen which includes nunit testing. It helps me see if my components are easy to develop with. Many times I have used ClassMaster for trouble shooting configuration problems on MOSS/WSS servers where the SharePoint UI does not give me enough information. Most of all I use ClassMaster because I like exploring the new functionality in SharePoint and .Net. It is very interesting to see the objects in action without having to code it all.