« April 2004 | Main | June 2004 »

May 2004

WSE 2.0 Released

WSE 2.0 has been released. Woohoo!

Web Services Enhancements 2.0 for Microsoft® .NET (WSE) is a supported add-on to Microsoft Visual Studio® .NET and the Microsoft .NET Framework that enables developers to build secure Web services based on the latest Web services protocol specifications.

Download here.

Enterprise Service Application reconfiguration

I'm currently writing an application which needs to support various scenarios for automatic reconfiguration of Enterprise Service properties. In essence, the application should expose a ServicedComponent which provides methods to dynamically reconfigure itself and its hosting application. I just thought that maybe someone else might be interested in a step-by-step explanation about how to do this:

My first step was to extend AssemblyInfo.cs to include some constants which will be used to generate the COM+ application ID and name:

using System.Reflection;
using System.Runtime.CompilerServices;
using System.EnterpriseServices;

[assembly: ApplicationActivation(ActivationOption.Library)]
[assembly: ApplicationName(MyApplicationInfo.COMPLUS_APP_NAME)]
[assembly: ApplicationID(MyApplicationInfo.COMPLUS_APP_GUID)]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyKeyFile(@"..\..\..\perfkey.snk")]

public class MyApplicationInfo
{
   public const string COMPLUS_APP_GUID=  "{E678632B-5F9C-4d9b-B204-61E14D4BE913}";
   public const string COMPLUS_APP_NAME=  "Some Demo Application";
}

I then generated a strongly-named interop wrapper for ComAdmin by running:

tlbimp c:\windows\system32\com\comadmin.dll 
     /asmversion:1.0.0.0 /keyfile:perfkey.snk /sysarray

The COMAdmin components allow you to directly access and modify settings of your Enterprise Service components, like security, transactions, activation, and so on. I used GetCollection("Application") and PopulateByKey(...) to load the information for my own application. (Note: If you have the VS.NET 2003 MSDN Library installed, you can find more information about the properties which can be configured at here and (for settings pertinent to applications) here. After changing any properties, you have to call SaveChanges() on the collection object.

using System;
using System.EnterpriseServices;
using COMAdmin;

public class TestConfigurator: ServicedComponent
{
   private ICatalogCollection GetMyInformation() 
   {
      COMAdminCatalog cat = new COMAdmin.COMAdminCatalog();
      object[] queries = new object[1];
      queries[0] = MyApplicationInfo.COMPLUS_APP_GUID;
      Array arr = (Array) queries;
      cat.Connect("localhost");
      COMAdminCatalogCollection apps = 
           (COMAdminCatalogCollection) cat.GetCollection("Applications");
      apps.PopulateByKey(arr);

      if (apps.Count==0)
      {
         throw new Exception("COM+ Application '" + 
             MyApplicationInfo.COMPLUS_APP_NAME + "' not found.");
      }

      return apps;
   }

   public void DisableAuthentication()
   {
      ICatalogCollection apps = GetMyInformation();
      ICatalogObject myApp = (ICatalogObject) apps.get_Item(0);
      myApp.set_Value("Authentication", 
          COMAdminAuthenticationLevelOptions.COMAdminAuthenticationNone);
      apps.SaveChanges();
   }

   public void EnableAuthentication()
   {
      ICatalogCollection apps = GetMyInformation();
      ICatalogObject myApp = (ICatalogObject) apps.get_Item(0);
      myApp.set_Value("Authentication",
          COMAdminAuthenticationLevelOptions.COMAdminAuthenticationDefault);
      apps.SaveChanges();
   }

   public void SwitchToLibraryActivation()
   {
      ICatalogCollection apps = GetMyInformation();
      ICatalogObject myApp = (ICatalogObject) apps.get_Item(0);
      myApp.set_Value("Activation", "Inproc");
      apps.SaveChanges();
   }

   public void SwitchToServerActivation()
   {
      ICatalogCollection apps = GetMyInformation();
      ICatalogObject myApp = (ICatalogObject) apps.get_Item(0);
      myApp.set_Value("Activation", "Local");
      apps.SaveChanges();
   }
}

These settings will be applied immediately for the next component activation (i.e. "SomeServicedComponent x = new SomeServicedComponent()"). If your E/S application for example contains an additional component MyTestComponent, you can run client-side code like the following to test both activation scenarios:

class clientApp
{
   static void Main(string[] args)
   {
      TestConfigurator cnf = new TestConfigurator();

      MyTestcomponent tst = new MyTestcomponent();
      // the following will be executed in library-activation (in-process)
      tst.DoSomething();

      Console.WriteLine("Switching to Server-Activation");
      cnf.SwitchToServerActivation();
      tst = new MyTestcomponent();
      // the following will be executed in server-activation 
      // (out of process)
      tst.DoSomething();

      Console.WriteLine("Switching back to Library-Activation");
      cnf.SwitchToLibraryActivation();
      tst = new MyTestcomponent();
      // the following will again be executed in library-activation mode 
      // (in-process)
      tst.DoSomething();

      Console.WriteLine("Done");
      Console.ReadLine();
   }
}

Quite nice, isn't it?

ASP.NET and RemotingConfiguration.Configure()

Robert just pointed out a bug in one of my Remoting FAQ articles. If you use ASP.NET as a Remoting client, you should not use this code in your app.config:

protected void Application_Start(Object sender, EventArgs e)
{
   RemotingConfiguration.Configure(Server.MapPath("client.exe.config"));
}

Using Server.MapPath(), some requests might fail if the application is recycled and the first request is not for a file in the application's root directory but in a subdirectory (i.e. "http://yourhost/somedir/default.aspx" instead of "http://yourhost/default.aspx". Robert suggested to use the following (and of course, he's totally right):

protected void Application_Start(Object sender, EventArgs e)
{
   RemotingConfiguration.Configure(Request.PhysicalApplicationPath + "client.exe.config");
}

Thanks, Robert!

Hooked on Skype

Today, Scott "the German who doesn't speak German" Hanselman introduced me to one of best pieces of software I've seen in the last time: Skype [http://www.skype.com]

Skype is a free, non-adware P2P voice over IP application (from the makers of kazaa) which doesn't force you to reconfigure your firewall and which provides voice quality which is better than, or at least comparable to a phone. With no noticeable lag and no blank-out periods like transatlantic phone calls.

It rocks for me because a lot of my friends are distributed amongst five different continents and Skype allows me to keep in touch with them better than IM would allow me to. Today I've already talked to friends in the US and Africa just as easily as using IM. I'm impressed.

thinktecture.com is online

It's been a long journey which took us several months, hundreds of emails, and hours of phone conferences and meetings throughout Europe. Today we've reached our most important milestone: thinktecture is going online.

Thinktecture offers in-depth consulting for software developers and architects. What we did was essentially to look at all the projects and customer with which we've worked in the previous years to distill a best practices approach for supporting .NET and web services projects. You can read more about this idea here. Our work is always focused on solving your current's projects needs while at the same time increasing your skill set.

We also wanted to allow for one thing: total confidence in our staff. We've therefore selected a team in which everyone has demonstrated his experience with writing successful books and articles, and in which everyone has excellent communication skills and is also a sought-after speaker for software development conferences around the world. Just check out our team and tell me what you think of our selection!

Even if you are not looking for consulting or support in your projects, we will have something for you as well: We've made arrangements with some international publishers which will allow us to continuously create and add new original, high-quality content to our site. I can't tell you too much right now, but the best way to keep informed about new articles is to subscribe to our new thinktecture blog using your favorite RSS reader.

I personally would really like to hear what you think of thinktecture. What do you think of our services? Do you like the team? Would there be anything your project needs which isn't part of our offerings? Do you have any further ideas on how we could improve our value for your - or others' - projects? You can reach me at any time by email or msn messenger at ingo.rammer@thinktecture.com or - for voice conversations - as "ingorammer" on Skype.