Monthly Archives: March 2010

A real JavaScript and CSS include method

After being displeased with the lack of a real JavaScript include method, and the complete absence of a CSS include method in ASP.NET, I started putting this into all of my BasePage classes. It uses Page Context to protect itself from double entries.

        protected void RegisterJavaScriptInclude(string path)
        {
            if (!Context.Items.Contains(path))
            {
                HtmlGenericControl js;
                js = new HtmlGenericControl();
                js.TagName = "script";
                js.Attributes.Add("type", "text/javascript");
                js.Attributes.Add("src", path);
                Page.Header.Controls.Add(js);
                Context.Items.Add(path, "JSINCLUDE");
            }
        }

        protected void RegisterCssInclude(string path)
        {
            if (!Context.Items.Contains(path))
            {
                HtmlGenericControl css;
                css = new HtmlGenericControl();
                css.TagName = "link";
                css.Attributes.Add("rel", "stylesheet");
                css.Attributes.Add("type", "text/css");
                css.Attributes.Add("href", path);
                Page.Header.Controls.Add(css);
                Context.Items.Add(path, "CSSINCLUDE");
            }
        }

How to post code on WordPress

This is probably obvious to those of you who have been using WordPress for a while. For the rest of us:

http://en.support.wordpress.com/code/posting-source-code/


Clone Wars: Object copy using reflection

Ever needed to copy the properties of one object to another where the objects did not inherit from an Interface or Abstract class? In defense of the pragmatic programmer, this situation should never happen. However, I have run into this situation twice when dealing with web services from an external Java source. You first must call a Session service to get a “ticket” back that must be included at the top of each subsequent web service request. The session object is just an xml serialized object that must be deserialized into a SessionObject. The problem is that when Visual Studio creates the proxy against the WSDL for the other services, they each encapsulate their own version of SessionObject. Even though they have the same schema, they are not the same object to .NET. This particular web service suite requires this type of object sharing a lot, so I created a helper function that would simplify the object copy using reflection. The thing I like is that you could theoretically fill a simple object based on a more complex object that contained more properties.
private object CopyObject(object objSource, object objTarget)
{
  Type typeSource = objSource.GetType();

  foreach (PropertyInfo propTarget in objTarget.GetType().GetProperties())
  {
     PropertyInfo propSource = typeSource.GetProperty(propTarget.Name);
     object valueSource = propSource.GetValue(objSource, null);

     if (propSource.PropertyType.Equals(propTarget.PropertyType))
     {
        propTarget.SetValue(objTarget, valueSource, null);
     }
     else if (valueSource == null)
     {
        propTarget.SetValue(objTarget, null, null);
     }
     else
     {
        object newTarget = Activator.CreateInstance(propTarget.PropertyType);
        newTarget = CopyObject(valueSource, newTarget);
        propTarget.SetValue(objTarget, newTarget, null);
     }
  }

  return objTarget;
}


Die, Die My Darling: a GAC alternative

The Global Assembly Cache is an excellent feature and does provide a solution to prevent DLL Hell (if you are a software company with a release strategy that is). What about the rest of us that live in the real world with aggressive timelines and budgets. We have one release called “Production”. The GAC is a decent solution for the globalization of custom framework and helper assemblies for a suite of applications, but not the right solution for most of us, especially those in the corporate sector.

The Pros: globalized assemblies, supports multiple concurrent versions, assemblies usually run with full trust, can be installed/uninstalled with a setup project.

The Cons: cannot be xcopy deployed, gacutil is unreliable, must physically be on the machine as an administrator to install, IIS applications do not automatically restart after a DLL is published, complicates the development cycle.

What are the alternatives? If the GAC was all-that-and-a-bag-o-chips you wouldn’t see forum after forum post asking for ways to get around it.

All of my applications (ranging from ASP.NET to Windows Services) reference a fairly large central framework that handles database actions, caching, encryption, etc. Trying to copy this DLL around could mean deploying it to 25 or more different bin directories (and the list will continue to grow). This would have forced me to create a fairly robust automated deployment mechanism comprised of manifests and such. Yuck. My previous solution was to use the GAC — a very hard sell to someone like me in the first place. After months of compounding small frustrations, I decided to look for alternatives. The answer is surprisingly simple, yet nearly impossible to find searching the Internet.

Information on assembly binding can be found here: http://msdn.microsoft.com/en-us/library/0ash1ksb.aspx

Basically this will redirect JIT compiler to an alternate assembly file when it attempts to compile the library. There was one trick which threw me off for a day or two getting this to work. CodeBase only accepts an HREF not a file path. You must use the URL file path syntax you might see when accessing a directory through Internet Explorer. The benefits of this method are the same as using assemblies directly in the bin folder, but you only have to deploy to a single location. You can even point to different versions for different applications if necessary.

<runtime>
<assemblyBinding xmlns=”urn:schemas-microsoft-com:asm.v1″>
<dependentAssembly>
<assemblyIdentity name=”nBaked” publicKeyToken=”2a6f8gc6611eh9s1″ culture=”neutral” />
<codeBase version=”1.0.0.0″ href=”file:///C:/nBaked/bin/nBaked.dll” />
</dependentAssembly>
</assemblyBinding>
</runtime>