January 2008 - Posts

A Little Intro to K2 Blackpearl

We've just finished going through a five days training course on K2 Blackpearl at my workplace.  In summary, K2 Blackpearl is a development platform for building workflow enabled applications that sits on top on Windows Workflow Foundation, and it also provides you a way to manage your business processes.  If you wish to know more about it you can check it here.

If you are thinking about OBA, this might be a good way to introduce it into your environment.  It integrates well with Windows SharePoint Services 3.0 / MOSS 2007. Office applications, especially InfoPath and Visio, and for the developer out there, VIsual Studio (at the moment, only VS 2005 Professional.  At least that's what the installer required to continue.  It might work with 2008 later on, but I haven't got any clear hint yet from the K2 rep / trainer regarding this).

It also has an entity concept they call SmartObject which I think is ADO.NET Entity Framework on steroid.  At least compared to the current implementation of ADO.NET Entity Framework anyhow.  SmartObject technology allows you to create entity that can be composed of other SmartObject entities or ServiceObjects entity.  What this mean to the business is that you can leverage data from different / decentralized systems as single entity. d5f02ecd Imagine pulling some Employee data that is only available on system A and some other Employee data that is only available on system B and present them as a global Employee entity.  Any update you do on the new global Employee entity will be pushed back to the appropriate backend systems.  This also include transaction support so if an update on system B failed, while system A is already updated, it will rollback the entire updates.  It even has its own ADO.NET Data Provider that will enable you to expose your SmartObjects to other application through SQL query. Very cool. 

Speaking on integration with Visio, your BA (business analyst) can now describe the business process as a diagram in Visio and K2 provides a VSTO extension to Visio that enabled BA / developer team the ability to map the business process diagram to K2 process diagram right inside Visio.  It's as simple as right-clicking on the particular diagram part and choosing a K2 workflow option that will launch a wizard-like interface that will walk you through the integration process.  The Visio K2 enabled diagram can then be exported to a Visual Studio K2 Blackpearl Workflow solution that can be handed over to the development team to be worked on further.

On the MOSS side, K2 Blackpearl allows business users to create their own simple document routing workflow solution right from within SharePoint.  Yes, SharePoint has its own workflow solution, but trust me, this one is a lot better than the standard workflow solution in SharePoint.  Creating an InfoPath Form solution is a breeze.  Starting from consuming SmartObject as a data source in your form to InfoPath SharePoint integration

onionheadfake9What I like most about this product is that it allows you to cut a workflow enabled application really fast.  If you don't have a complex process that will require coding, you can implement your application without cutting a single line of code.  Compared to developing directly in Windows Workflow Foundation, this will make your life a whole lot easier.  Rapid prototyping is a piece of cake with this tool.

It also comes with its own Workspace AJAX application that will enable you to manage, troubleshoot and obtain reports on your business processes.  You can track each process instance and at what stage each instance is  graphically as the workflow process diagram gets updated everytime an action is performed.

Just a little side track, on the last day of the training, we went through how to install a K2 server farm. Boy, did I learn a lot about IT related skill there.  Although familiar with the concept of DNS, NLB (Network Load Balancing), Clustering, SPN, Kerberos, etc.  I've never really got my hand quite this dirty in the real implementation of such thing on Windows platform.  It sure is fun learning these kind of stuffs.

On the workflow side, you can make it as simple as possible (design in SharePoint click and drag style, design in Visio and integrate, design in VS click and drag with Wizard interface) or you can choose to dive in deep to the WF code level if you need to.

Can't wait to play more with this thing.

For those who are already using K2.NET 2003, you should really consider upgrading to K2 Blackpearl.  It's much easier to use, develop in and manage. There are still some bugs in the product but they're not showstopper ones (at least so far that we've found out).

967339c1Happy K2-ing.

Share this post: | | | |
Posted by Jimmy Chandra | 2 comment(s)
Filed under:

Playing Around with Anonymous Type, Extension Method, LINQ, and Generic

I was reading this particular entry from AlexJ's blog, in which he discussed how to use anonymous type returned from one function in another function.  I strongly recommend you read it first before reading any further.

Basically, most people would think that there is no easy way to return a strongly typed anonymous type from a function since you wouldn't know what it is that you are returning beforehand. Thus, if you wish to return an anonymous type from a function, you are forced to return it as object like so:

   1:          object CreateAnonymousObject()
   2:          {
   3:              return new { Name = "John Doe" };
   4:          }

The problem of doing it like this is that you lost the ability to access the Name property since object does not have a Name property.  So, your option is to cast it back to its original anonymous type, but alas, how could you do it?

It turned out that there is a way to do this using generic.  If you create a generic function that will return a generic type T and also pass an object of type T in the parameter, you can cast whatever object that you pass as T.  In effect, you are using the object of type T as your example to cast the boxed object to.  See the following code:

   1:  T CastByExample<T>(object source, T example)
   2:  {
   3:      return (T)source;
   4:  }

So now, you can do something like this (for the sake of clarity, I am not going to shorthand these examples):

   1:  var o = CreateAnonymousObject();
   2:  var prototype = new { Name = "" };
   3:  var result = CastByExample(o, prototype);
   4:  Console.WriteLine(result.Name); //This should work just fine

To make things a little bit easier to read, we can use the new extension method feature of .NET 3.5 like so:

   1:  public static class MyExtensions
   2:  {
   3:      public static T CastToTypeOf<T>(this object source, T example)
   4:      {
   5:          return (T)source;
   6:      }
   7:  }

And rewrite the example to:

   1:  var o = CreateAnonymousObject();
   2:  var prototype = new { Name = "" };
   3:  var result = o.CastToTypeOf(prototype);
   4:  Console.WriteLine(result.Name); //This should work just fine.

This is great.  I don't know what I am going to use it for, but it's nice to know that I can do it when I need it.

And then, another idea comes to my mind.  Hey, what if we need to do similar thing to an anonymous object collection.  How could I do that? How could one creata a generic list of anonymous object?  As it turned out, Kirill Osenkov already solve this particular problem.  You can see it here.

So, let's come up with something interesting to explore this problem.  Lets say that you are querying a Contact database through LINQ, but instead of returning the entire Contact fields, you wish to only return some of them.

Making thing simpler, I decided to mock the Contact class like so (too lazy to create a dbml, so I am querying from in-memory object :) ):

   1:  public class Contact
   2:  {
   3:      public string FirstName { get ; set; }
   4:      public string LastName { get; set; }
   5:      public string PhoneNumber { get; set; }
   6:      public string StreetAddress { get; set }
   7:      public string City { get; set; }
   8:  }

And here is an example function that will return you a list of Contacts:

   1:  IEnumerable<Contact> GetContacts()
   2:  {
   3:      return new List<Contact> {
   4:          new Contact { FirstName = "John", LastName = "Doe", PhoneNumber = "555-5501", StreetAddress = "123 Lala Lane", "Los Angeles" },
   5:          new Contact { FirstName = "Jane", LastName = "Doe", PhoneNumber = "555-5502", StreetAddress = "567 Lala Lane", "New York" }
   6:      };
   7:  }

And you only wish to return the FirstName and LastName from your LINQ query like so:

   1:  var query = from c in GetContacts()
   2:              select new { Name = c.FirstName + " " + c.LastName };

Again, for whatever reason, you really really want to encapsulate this as a method, so, you do something like this:

   1:  object GetContactNamesFrom(IEnumerable<Contact> contacts)
   2:  {
   3:      var query = from c in contacts
   4:                          select new { Name = c.FirstName +  " " + c.LastName };
   5:      return query.AsEnumerable();
   6:  }

Great!  Now you have something that can return a generic collection of an anonymous type.  But how can we use this in our own function and allow our function to access the Name property?

Well, combining what we've learnt so far, we can come up with something like this...

First, we know we can now cast something to an anonymous type (sort of) using the generic method CastByExample or CastToTypeOf as seen above.

Second, we need a way to create an anonymous collection.

Let's start with the second one first.  We need a way to create an anonymous collection.  So let's think about this a bit.  i hope you've read the blog post by Kirill by now.  If not, well, here is how you do it...

   1:  IEnumerable<T> CreateEnumerablesByExample<T>(T example)
   2:  {
   3:      return new List<T>();
   4:  }

Now you can do something like:

   1:  var prototype = new { Name = "" };
   2:  var prototypeCollection = CreateEnumerablesByExample(prototype); //This is now a generic collection of anonymous.

What's left for us to do is cast our LINQ result back as the prototypeCollection so we can get access to the Name property from our code like so:

   1:  var contactInfo = GetContactNamesFrom(GetContact());
   2:  var prototype = new { Name = "" };
   3:  var prototypeCollection = CreateEnumerablesByExample(prototype);
   4:  var result = contactInfo.CastToTypeOf(prototypeCollection);
   5:   
   6:  foreach(var c in result)
   7:  {
   8:      Console.WriteLine(c.Name);
   9:  };

We can do one better by using extension method.  Let's refactor CreateEnumerableFrom as an extension method like so:

   1:  public static IEnumerable<T> CreateEnumerablesOfThis<T>(this T prototype)
   2:  {
   3:      return new List<T>();
   4:  }
 

The refactored code of our final example will look like this:

   1:  var contactInfo = GetContactNamesFrom(GetContact());
   2:  var prototype = new { Name = "" };
   3:  var protoypeCollection = prototype.CreateEnumerablesOfThis();
   4:  var result = contactInfo.CastToTypeOf(prototypeCollection);
   5:   
   6:  foreach(var c in result)
   7:  {
   8:      Console.WriteLine(c.Name);
   9:  }

So, why would go through all these trouble?  Honestly, I have no idea.  I am just exercising my brain just to see if I can do such a thing.  I have no real need for this type of things yet.  Who knows... maybe someday...

Share this post: | | | |

Team Foundation Server 2005 Installation (Mis)Adventure

imageIt started last week on Friday, January 11th 2008 (Although in retrospect, it should really be a Friday the 13th sort of experience).

 

As a team we decided it's time to move our project source control from Visual SourceSafe to TFS.  I volunteered as a resource to do the TFS installation.  I was quite confidence with the rate of success since I previously completed a TFS Workgroup Edition installation successfully (just by following the installation guide). 

And so, this time around, we were going to install the full fledge TFS.  We've downloaded the installation source.  Unpacked it.  Read through the installation guide.  So far so good.  It appeared quite similar to what I did previously.  So I decided to just follow it step by step.

imageTo my horror, what I thought is going to be, at maximum, a day work turned into a four day strugglefest filled with tear, screaming and frustration, hehehe.

During the installation process, I ended up:

  1. Scrapping the TFS VM three times (once per day).
  2. Creating lots of snapshots so I could revert back to when I knew the system was working correctly.
  3. Calling two other resources which have a better knowledge on SharePoint inner workings than myself.
  4. Scrounging the web for scraps of information on why the heck TFS Project Creation kept blowing up in my face (see this post in MSDN forum) and SQL SSIS not working after installing SQL Server 2005 SP1.
  5. Wanting to recreate the entire VM from scratch instead of installing from a base of Windows Server 2003 SP 2.
  6. Wanting to reinstall the TFS Workgroup Edition instead of the full TFS just to prove that it did work and installed easily.
  7. Fiddling around with the VM DNS settings due to a problem that rear its ugly head (For whatever reason I couldn't add / search for a Domain user to my local group from Computer Management console).
  8. Joining and leaving the Domain at least 10 times due to problem in #7.
  9. Rebooting the silly VM at least 20 times due to #8.

And you know what finally solved my TF30162 (Can't create TFS project) problem...?

Changing the stupid DOMAIN\TFSSERVICE account to be a Local Administrator on the TFS machine.  Damn it, wasted four freaking days just to figure this out.

And you know why it took that long...?image

I followed the freaking installation guide word for word, which you can find here.  

The following is word for word quote of the User Account requirement from the installation guide:

TFSSERVICE
Used as the service account by Team Foundation Server Windows services (Code Coverage Analysis Service and TFSServerScheduler), and the SharePoint Timer Service.

Used as the application pool identity by the Team Foundation Server application pool (TFS AppPool), and the Windows SharePoint Services application pools (TFWSS and TFSWSSADMIN).

For optimal security, this service account:

Should not be an administrator on Team Foundation Server computers.

Should have the option Account is sensitive and cannot be delegated selected for Active Directory on the domain.

imageHehehe.  Non Admin My Butt.  Microsoft, please fix the silly installation guide :).

 

 

Share this post: | | | |
Posted by Jimmy Chandra | 9 comment(s)
Filed under:

Adapter Pattern Case Study: LINQ to SharePoint SPListCollection

While helping my co-worker on a problem we stumbled into a quite interesting thing regarding SharePoint SPListCollection class.

SPListCollection, as it turns out, is not derived from IEnumerable interface (see http://msdn2.microsoft.com/en-us/library/ms998307.aspx). 

The inheritance chain is basically as follow: System.Object -> Microsoft.SharePoint.SPBaseCollection -> Microsoft.SharePoint.SPListCollection.

The problem that we encountered was that it was impossible to query the SPListCollection directly using LINQ since it does not implement IEnumerable interface.

A couple design patterns popped up in my head.  One of them is Iterator pattern and the other one is an Adapter pattern.

The first one allows us to iterate over member of a list.  The later is to wrap an object and transform its interfaces to suit the interface of our consuming object.

We need an adapter to transform the current SPListCollection object into something that can be enumerated by LINQ.  I decided that the fastest way to do this is to wrap a real SPListCollection object inside a generic List<SPList> collection.  The resulting code can be found at http://asadewa.wordpress.com/2008/01/03/linq-ing-splistcollection/.

The trade of of this implementation is that you are basically accessing a snapshot of a real SPListCollection at a given point in time since we are copying all the SPList objects inside SPListCollection into our own collection.  I suggested that we also implemented a Refresh method to allow user to refresh the list when needed.

A second method that we didn't pursue is to implement an IEnumerable<SPList> interface inside our adapter.  The consequence of doing so is that we have to create our own IEnumerator implementation also.  The advantage of doing it this way are that we only expose things that we want to expose to the consuming object instead of exposing a whole lot of other methods and properties that might not necessary apply to our own design (i.e. deriving from List<SPList> will allow you to Add, Remove, etc. which we really dont need at this point in time) and we do not need to copy the inner list of our original collection into our own collection.  We just need to add logic on how to iterate over the original collection items.

In short, the first method is to wrap and copy the individual list items in our own list implementation and iterate through the new collection and the second one is purely wrapping the original list and provide methods and interfaces to iterate through the original list.

The first method requires more memories while the second one does not.  The first method is easy and fast to implement while the second requires a little bit more effort on the programmer's side. Which is better?  I'll leave that up to you.

Happy Patterning.

Share this post: | | | |
Posted by Jimmy Chandra | 1 comment(s)
Filed under: , ,