Saturday, April 01, 2006
How to use mage.exe in conjunction with the ClickOnce MSBuild tasks to resolve the deficiencies with the Visual Studio ClickOnce mechanism.
posted on 4/1/2006 12:11:29 AM (Pacific Standard Time, UTC-08:00)  #    Comments [35]
 Sunday, July 31, 2005

I’m using a number of SoapExtensions in my current project and had a need to register them dynamically on the client side; Christian Weyer blogged about a solution using reflection which injects the extension into the in-memory config.  This works great for .NET 1.x, but I’m all over .NET 2.0 code these days!  Unfortunately, dynamically registering SoapExtensions gets no easier in 2.0, but fortunately hacking the in-memory config does:

/// <summary>
/// Programatically registers a <see cref="SoapExtension"/> at runtime with the specified
/// <see cref="SoapExtensionTypeElement.Priority"/> and <see cref="SoapExtensionTypeElement.Group"/> settings.
/// </summary>
/// <param name="type">The <see cref="Type"/> of the <see cref="SoapExtension"/> to register.</param>
/// <param name="priority">
/// A value that indicates the relative order in which this SOAP extension runs when multiple SOAP extensions are
/// specified. Within each group the priority attribute distinguishes the overall relative priority of the SOAP
/// extension. A lower priority number indicates a higher priority for the SOAP extension. The lowest possible
/// value for the priority attribute is 1.
/// </param>
/// <param name="group">
/// The relative priority group (e.g. Low or High) in which this SOAP extension runs when multiple SOAP extensions
/// are configured to run.
/// </param>
[ReflectionPermission(SecurityAction.Demand, Unrestricted = true)]
public static void RegisterSoapExtension(Type type, int priority, PriorityGroup group)
{
   if (!type.IsSubclassOf(typeof(SoapExtension)))
   {
      throw new ArgumentException("Type must be derived from SoapException.", "type");
   }

   if (priority < 1)
   {
      throw new ArgumentOutOfRangeException("priority", priority, "Priority must be greater or equal to 1.");
   }

   // get the current web services settings...
   WebServicesSection wss = WebServicesSection.Current;

   // set SoapExtensionTypes collection to read/write...
   FieldInfo readOnlyField = typeof(System.Configuration.ConfigurationElementCollection).GetField("bReadOnly", BindingFlags.NonPublic | BindingFlags.Instance);
   readOnlyField.SetValue(wss.SoapExtensionTypes, false);

   // inject SoapExtension...
   wss.SoapExtensionTypes.Add(new SoapExtensionTypeElement(type, priority, group));

   // set SoapExtensionTypes collection back to readonly and clear modified flags...
   MethodInfo resetModifiedMethod = typeof(System.Configuration.ConfigurationElement).GetMethod("ResetModified", BindingFlags.NonPublic | BindingFlags.Instance);
   resetModifiedMethod.Invoke(wss.SoapExtensionTypes, null);
   MethodInfo setReadOnlyMethod = typeof(System.Configuration.ConfigurationElement).GetMethod("SetReadOnly", BindingFlags.NonPublic | BindingFlags.Instance);
   setReadOnlyMethod.Invoke(wss.SoapExtensionTypes, null);
}

posted on 7/31/2005 12:10:42 PM (Pacific Standard Time, UTC-08:00)  #    Comments [8]
 Monday, May 02, 2005

There is a fundamental problem with System.Web.Caching.Cache -- what if your application is not a web application and you need some general-purpose cache functionality (e.g. middle-tier logic)? Since there is no equivilent "System.Caching.Cache" class I decided to write one using weak references that has no dependency on System.Web.dll.

posted on 5/2/2005 8:12:59 AM (Pacific Standard Time, UTC-08:00)  #    Comments [5]
Contains several useful classes that fill-in some holes with the current BCL Queued Components (QC) implementation. Functionality includes automatic queue moniker construction, QC session management (both synchronous and asynchronous), a QC exception handler base class, a QC custom config section handler, a managed wrapper class for the COM+ Message Mover object, and an object wrapper to marshal .NET serializable types in queued interface calls. Full source code, documentation and samples are provided.  Download it here.
posted on 5/2/2005 8:06:51 AM (Pacific Standard Time, UTC-08:00)  #    Comments [1]
 Sunday, May 01, 2005
Why wait for Whidbey to get debugger visualizers when you can get one today?
posted on 5/1/2005 8:56:15 PM (Pacific Standard Time, UTC-08:00)  #    Comments [10]