Tuesday, June 24, 2008

MOSS 2007 Certification (70-542)


After my WSS Certificate yesterday, I passed the MOSS Developer exam (70-542) today with 969 points.
So now "I know everything" of InfoPath WebForms, the Business Data Catalog, Sharepoint Search, Audiences, Excel Web Access & Report Services, SharePoint Portals, Policies & Record Repositories, etc. etc... and have the MCTS: Microsoft Office SharePoint Server 2007 – Application Development certification.

Monday, June 23, 2008

WSS3.0 Certification (70-541)

WSS thumbnail I did my 70-541 certification exam today, and passed with a score of 972! Altough the exam was tough, I'm again in the books for the 70-542 (MOSS2007) exam, tomorrow mornig.

So what I've learned? Building webparts, features, site templates, workflows, custom fields, events, etc., etc....

What I've earned? Another MCTS on my CV ;)

Tuesday, June 17, 2008

Generics with Actions

An action is pointer to a function with no return value which you can use for working with generic lists. It looks like the Predicate functions, but the referenced method won't return a boolean value.

Still, the only parameter in the function is of the type of the generic. In this example, I extend the DateRange class with an Action.

An example of such an implementation:

/// <summary>
/// DateRange is a helper class to work with dates
/// </summary>
public class DateRange
{
private DateTime _startDate = DateTime.MinValue;
private DateTime _endDate = DateTime.MaxValue;

public DateTime StartDate
{
get { return _startDate; }
}
public DateTime EndDate
{
get { return _endDate; }
}

public DateRange(DateTime startDate, DateTime endDate)
{
_startDate = startDate;
_endDate = endDate;
}

/// <summary>
/// Gets the IsInPeriod method.
/// </summary>
/// <value>The in period.</value>
public Predicate<DateTime> InPeriod
{
get { return IsInPeriod; }
}

/// <summary>
/// Determines whether the specified date is in the period set by startdate and enddate.
/// </summary>
/// <param name="date">The date.</param>
/// <returns>
/// <c>true</c> if the specified date is in the period; otherwise, <c>false</c>.
/// </returns>
private bool IsInPeriod(DateTime date)
{
if ((date >= StartDate) && (date < EndDate))
{
return true;
}
else
{
return false;
}
}

/// <summary>
/// Gets the WriteNumberOfDaysFromStartDate method.
/// </summary>
/// <value>The write number of days till end.</value>
public Action<DateTime> WriteNumberOfDaysFromStart
{
get { return WriteNumberOfDaysFromStartDate; }
}
/// <summary>
/// Writes the number of days from the start date of the period.
/// </summary>
/// <param name="date">The date.</param>
private void WriteNumberOfDaysFromStartDate(DateTime date)
{
Console.WriteLine("{0} days to go", ((TimeSpan)(date - StartDate)).Days);
}
}


You can now use this conditional predicate with different Generic methods.

public class ActionExamples
{
public static void Main()
{
// fill an example list
List events = new List();
events.Add(DateTime.Now.AddDays(-1));
events.Add(DateTime.Now.AddDays(-2));
events.Add(DateTime.Now);
events.Add(DateTime.Now.AddDays(1));
events.Add(DateTime.Now.AddDays(2));
events.Add(DateTime.Now.AddDays(3));
events.Add(DateTime.Now.AddDays(4));

//create a DateRange object for tomorrow
DateRange nextMonth = new DateRange (new DateTime(2008,7,1), new DateTime(2008,7,31) )

//get events for next month
List nextMonthEvents = events.FindAll(nextMonth.InPeriod);

//write days from start of nextMonth to console
events.ForEach(nextMonth.WriteNumberOfDaysFromStart);
}
}

Monday, June 16, 2008

Generics with Predicates

A predicate is pointer to a boolean function which you can use for querying generic lists.
With these methods, coding against generic lists will be much easier. But one problem with these predicates is that the only parameter in the function is of the type of the generic. A solution for this is refactoring the predicate to a class, where you can provide these parameters to properties or the constructor.

An example of such an implementation:

/// <summary>
/// DateRange is a helper class to work with dates
/// </summary>
public class DateRange
{
private DateTime _startDate = DateTime.MinValue;
private DateTime _endDate = DateTime.MaxValue;

public DateTime StartDate
{
get { return _startDate; }
}
public DateTime EndDate
{
get { return _endDate; }
}

public DateRange(DateTime startDate, DateTime endDate)
{
_startDate = startDate;
_endDate = endDate;
}

/// <summary>
/// Gets the IsInPeriod method.
/// </summary>
/// <value>The in period.</value>
public Predicate<DateTime> InPeriod
{
get { return IsInPeriod; }
}

/// <summary>
/// Determines whether the specified date is in the period set by startdate and enddate.
/// </summary>
/// <param name="date">The date.</param>
/// <returns>
/// <c>true</c> if the specified date is in the period; otherwise, <c>false</c>.
/// </returns>
private bool IsInPeriod(DateTime date)
{
if ((date >= StartDate) && (date < EndDate))
{
return true;
}
else
{
return false;
}
}
}


You can now use this conditional predicate with different Generic methods.

public class PredicateExamples
{
public static void Main()
{
// fill an example list
List events = new List();
events.Add(DateTime.Now.AddDays(-1));
events.Add(DateTime.Now.AddDays(-2));
events.Add(DateTime.Now);
events.Add(DateTime.Now.AddDays(1));
events.Add(DateTime.Now.AddDays(2));
events.Add(DateTime.Now.AddDays(3));
events.Add(DateTime.Now.AddDays(4));

//create a DateRange object for tomorrow
DateRange tomorrow = new DateRange (DateTime.Today.AddDays(1), DateTime.Today.AddDays(2))

//get a boolean if there is an event tomorrow
bool tomorrowHasEvents = events.Exists(tomorrow.InPeriod);

//get events for tomorrow
List tomorrowEvents = events.FindAll(tomorrow.InPeriod);

//get first event for tomorrow (first item in list!)
DateTime tomorrowFirstEvent = events.Find(tomorrow.InPeriod);
//get last event for tomorrow
DateTime tomorrowLastEvent = events.FindLast(tomorrow.InPeriod);

//get the index of the first event for tomorrow
int tomorrowFirstEventIndex = events.FindIndex(tomorrow.InPeriod);
//get the index of the last event for tomorrow
int tomorrowLastEventIndex = events.FindLastIndex(tomorrow.InPeriod);

//remove all events for tomorrow
int removedItems = events.RemoveAll(tomorrow.InPeriod);

//are all events in the list tomorrow
bool allEventsTomorrow = events.TrueForAll(tomorrow.InPeriod);

}
}

Friday, June 13, 2008

.NET 2.0 = .NET 3.0 = .NET 3.5

Yesterday I had a discussion on an internal Microsoft Developers meeting about the status of .NET 3.5. We had presented that .NET 3.0 is an extension of .NET 2.0, and not a new version. My statement that the status of .NET 3.5 is the same, it is basically .NET 2.0 with extra features, was received sceptically.
Just to prove I'm right, here my observations.

Build a very simple .NET Console application, using two lines of code:

Console.WriteLine("Hello World");
Console.WriteLine("using version: {0}", System.Environment.Version.ToString());


With Visual Studio 2008, you can build this with all three version of the framework. And all three executables yields the same results: using version: 2.0.50727.1433.

ILDASM one of these assemblies gives the same assembly header:

// Metadata version: v2.0.50727
.assembly extern mscorlib
{
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 )
.ver 2:0:0:0
}


Proving all three versions are based on the .NET core version 2.0 (and this is the same version you should configure in ASP.NET. There is no v3 there).
Just to be sure if you want to upgrade to 3.5 at your customer to mention that version 3.5 also is basically .NET 2.0, with some extra features added. I won't say that the libraries of .NET 2.0 are the same with 3.5, but runtime versions are equal.

Rick Strahl blogged about this a while ago.