Run features in a separate AppDomain – level 300

Along with putting feature dlls in a separate directory with the shared assemblies they need, I like to run these features in an isolated AppDomain to contain memory usage as well as state.  When using Trace for logging, this is a great benefit because application state is local to the AppDomain, so my Trace.Listeners collection is dedicated to the AppDomain.  Here’s an easy sample showing how to do this:



            Trace.Listeners.Add(new TextWriterTraceListener(Console.Out));


            Trace.WriteLine(“Starting MainClass”);


       


            AppDomainSetup setup = new AppDomainSetup();


            setup.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory; // or another directory.


            setup.ApplicationName = “My Domain”;


            AppDomain ad = AppDomain.CreateDomain(“CreateDomain”, null, setup);


            object o = ad.CreateInstanceAndUnwrap(“BusinessLogic”, “BusinessLogic.BusinessLogic”);


            Trace.WriteLine(o.ToString());


       


            Trace.WriteLine(“DONE testing appdomain.  Now testing process”);


            Console.ReadLine();


And here is my BusinessLogic class I contrived for this test:



namespace BusinessLogic


{


    /// <summary>


    /// Summary description for Class1.


    /// </summary>


    [Serializable()]


    public class BusinessLogic : MarshalByRefObject


    {


        public override string ToString(){


            System.Diagnostics.Trace.WriteLine(“From Business Logic”);


            string retValue = “Information about current runtime:n”;


            retValue += “Current AppDomain location: ” + AppDomain.CurrentDomain.BaseDirectory + “n”;


            retValue += “Executing Assembly FullName: ” + Assembly.GetExecutingAssembly().ToString() + “n”;


            retValue += “BusinessLogic location: ” + Assembly.GetExecutingAssembly().Location + “n”;


            retValue += “Framework Assembly FullName: ” + typeof(Audit).Assembly.ToString() + “n”;


            retValue += “Framework location” + typeof(Audit).Assembly.Location + “n”;


            return retValue;


        }


        public override bool Equals(object obj) {


            throw new Exception(“BOMB”);


            return base.Equals (obj);


        }


    }


}


 


Notice how I marked the class as Serializable.  And don’t forget to mark other classes that  you may need to pass back and forth (not many, I hope).  I also have to inherit my object from MarshalByRefObject because my initial call is directly to this object.  Any exceptions that may be raised up back to the parent AppDomain must also be Serialiable and implemet a Serialization constructor. 


I love this model for code and state isolation, and it has made my life so much easier!

Avoid the GAC, prefer XCOPY. Here’s why – level 300

I know I may get some comments saying that the GAC should be used for shared
assemblies, but it’s so much easier to maintain XCOPY deployment with a
consuming assembly in a directory by itself with the shared assemblies it
needs. 

Let me give a scenario where I would do this:  I have a windows application
that is modularized into main features.  The base directory has the main
executable and all the shared libraries.  Feature teams work on the main
features and deploy the feature’s .dll files into a subdirectory along with the
version of the shared assemblies they compiled and tested against.  Maybe I
release a new version of the program shell (the main assembly).  That team has
to test against the most current build of the shared assembly and deploy.  The
feature assemblies aren’t retested and continue to use the assembly they were
tested with.  A single feature team can redeploy their feature along with the
current build (at that time) of the shared assembly.  The features are
completely decoupled and the deployment is easy. 

Consider the alternative:  the main executable and feature assemblies are
deployed to the same directory.  No matter the feature, the shared assembly in
the current directory is loaded.  I version the main EXE, and it needs the
latest version of the shared assembly.  I have a situation where I have to
retest all the features because they were built against an
older version of the shared assembly.  I have no way to version each major piece
separately.  Or if a feature team makes a new release, and they have to have the
latest shared dll, you have a major retest burden every time this happens.  If
you keep the binaries separate, you avoid this problem.

Put the shared assembly in the GAC, you say?  Yes, that would work.  If you
prefer it, go ahead, but what, really, is the benefit?  There is no
real performance difference.  It is another method that would
work, but there is no benefit to the increased deployment burden.  KISS.  Keep
it simple, stupid, that’s my motto.  The simplest thing that will work.  If I’m
wrong, I would love to hear the real benefits
of the GAC.

I’m not knocking the MS team who made the GAC, but XCOPY is just such a great
deployment model, why mess with a good thing?

Update on XmlSerializerSectionHandler – level 200

Here is another update to the XmlSerializerSectionHandler that Craig
Andera
introduced.  The code below is essentially the same:

    public
class
XmlSerializerSectionHandler : IConfigurationSectionHandler
{

 

        public
object
Create(object p_oParent, object p_oConfigContext, System.Xml.XmlNode
p_oSection) {

            XPathNavigator oNav =
p_oSection.CreateNavigator ();

            string sTypeName =
oNav.Evaluate(“string(@type)”).ToString();

            Type oType =
Type.GetType(sTypeName);

            XmlSerializer oSer = new XmlSerializer(oType);

            XmlNodeReader oReader = new XmlNodeReader(p_oSection);

            object oRetValue =
oSer.Deserialize(oReader);

            oReader.Close();

            return oRetValue;

        }

    }

 

I wanted to demonstrate how powerful this really is.  Not only can we now use
this to strongly-type our configuration keys as elements, but we can configure
arrays as well.  Here is my config section:


<configSections>


<section name=”MyConfig” type =”Dell.Titans.Framework.Configuration.XmlSerializerSectionHandler,
Dell.Titans.Framework”/>
</configSections>


<MyConfig type=”ConsoleTestHarness.MyConfig,ConsoleTestHarness”>
<List>
    
<
int>1</int>
     <int>2</int>
     <int>4</int>
</List>
<Foo>1.234</Foo>
<Bar>A bunch of
information
</Bar>
<ConnectionString>my string</ConnectionString>
</MyConfig>

Now the section name must be the same as the type name, but see how we can
configure an array of int object as the “List” property.  Here is my type:

    public
class
MyConfig {

        private
float
foo;

        private
string
bar;

        private
string
connectionString;

 

 

        public
float
Foo {

            get { return foo ; }

            set { foo = value ; }

        }

 

 

        public
string
Bar {

            get { return bar; }

            set { bar = value; }

        }

 

        public
string
ConnectionString {

            get { return connectionString; }

            set { connectionString = value; }

        }

 

        public
int
[] List = new int[]{1, 2, 4};

   

    }

 

Note how I have added one more property as well as the List array.  Another
thought is:  What if I add a method to the getter of ConnectionString to
unencrypt the value before returning it?  Then I could encrypt sensitive keys
without much effort.

The <appSettings> configuration section offers basic functionality, but
the configuration architecture is so flexible that we are able to customize
configuration to our exact needs.  Happy programming.

Use XHTML for your web applications, please! – level 100

I realize that a lot of web applications are targeted for IE, and it may be an intranet application.  Even so, it pays to put the line:

<!DOCTYPE html
PUBLIC “-//W3C//DTD XHTML 1.0 Strict//EN”
“http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd”>

Adding this will save you so much grief later on.   First, your CSS will actually cascade down to child elements, so you can have a very clean stylesheet.  Second, you know that your site will render properly in all browsers.  No need to test all the browsers.  By making your pages XHTML, you are adhering to the standard, so that’s all you need to worry about. 


The alternative is to muck up your stylesheet with duplicate declarations and the same css class on nested elements.  Then, when the site looks good, just open it in another standards-based browser and cry.


Many people don’t know that if you fail to put a doctype at the top of a page, IE will interpret it as HTML4.0.  If you want HTML4.0, then at least put the doctype there:


<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01//EN”
   “http://www.w3.org/TR/html4/strict.dtd”>
Even then, the other browsers (that default to XHTML) will see the doctype and interpret it as HTML4.


 


I wonder how many web application developers out there have never read the standards docs for xhtml or css. . .

Reverse engineering a project from the binaries after losing the source code – level 300

I just did this today, and it actually didn’t take long.  I inherited a project, and the source code did not come with it.  It’s a side project, not at my company, but I originally thought that I might have to start from scratch.  Normally, I probably would have, but by using Reflector I was able to leverage many of the existing objects.  The project is a web site with SQL Server behind it, and there are several controls that pull and display data from the website.  After putting my new website framework in place (EZWeb), I made plugins (user controls that are dynamically loaded) to house the existing controls.  I made a template (a user controls that works with my master page controls) to mimick the look of the original site.  Then I added the individual controls to my plugins.  Even when I received errors, I was able to use Reflector to drill down the call stack and figure out what was going wrong.  Now, I have the site on my EZWeb framework while leveraging the existing code.  It will be very easy to extend the site from here in the new direction, and I didn’t have to start from scratch. 


Scott, if you’re reading this, yes, it’s what you’re thinking of.

Eating at Rudy’s after a talk with Brad Abrams – level 000

Brad gave a great talk Friday at the Austin .Net User Group.  He covered the guts of Exceptions and Finalizers and the Dispose pattern.  Afterwards, we at at Rudy’s BBQ – the worst BBQ in Texas! (that’s the slogan).  Here’s some pics:



 


I’m the 4th one back on the right.

Stay away from job postings like this! – level 000

I came across this on a message board, and I just HAD to blog it:


Requirements(.Net Developer position):
*2 yrs exp programming in .NET.
*Exp with C# and VB.NET required.
*Experience with ActiveX DLL, EXE, and OCX programming required.
*Experience and knowledge with Windows 32 API.
*5 yrs exp with Structured Query Language including custom coded SQL logic.
*Strong understanding of database normalization.
*Experience with n-tier design including logical and physical model implementation.
*Experience in creating, changing, and collecting data using custom defined business objects.
*Prefer exp in Web and Palm development .
*Understanding of third party reporting tools (e.g. TxText Control, Crystal Reports).
*Understanding of object oriented principles and methodologies
*Experience using source control and change management procedures.
*Understanding of Microsoft Windows Installer (MSI) and creation of custom installation packages.
*Thorough understanding of data access techniques
*Must have strong attention to detail
*Must have experience working in a team environment and be able to interface with management and internal customers
* Prefer Bachelor’s degree in Computer Science, or Engineering. Minimum requirement is Associates degree or equivalent from two year college or technical school in Computer Information Systems or Programming Certification.

Pay Rate:  up to $29/hour


 


#1 and 2 seem reasonable, and I meet that.  OCX programming???  I’ve NEVER done that.  By the way, is this .Net developer position going to require daily OCX programming??  Give me a break?  n-tier design:  This candidate must have experience implementing both logical AND physical designs.  Well, I’m disqualified because I’ve never implemented a logical design.  Then there is Palm development.  Never done that. . .and then who can understand Crystal Reports (I mean REALLY understand it?). 


Then at the bottom, there is the college requirement.  And then for this super-developer, they want to pay up to $29 per hour???  What a laugh!  Most of the time, it will take 3 or more people to get all these skills, and they want one to work for $29.  That’s great.  They’ll get what they’re willing to pay for:  someone who lies on his resume about all these things and can stumble his way through to something that works (for up to 3 users). 


These job postings are all over the place.  The recruiters don’t have a clue who they need to hire.  Targeted job postings impress me.  They have required skills (what the job needs on a daily basis), and that’s it.  And usually the rate of pay is only mentioned when it is low.  My advice to anyone reading is to stay away from the above job.  This reeks of poor management and an environment of frustration.  May ye be warned.

Watch out for this MSN IM virus – level 200

You need to read: http://www.sarc.com/avcenter/venc/data/w32.bropia.m.html


If you get an IM message (even from someone you know) that reads something like this: LOOK! http://members.chello.nl/g.geurts1/handcuffs.XYZ. . . .  Don’t click on it.  If you do, you’ll need to clean it before rebooting because it adds an executable to your run-once list. 

If you are skeptical of everything and don’t click, you are safe.  I know a LOT of people who have been affected by this.

If your mind can’t keep up with your fingers – level 100

I learn things from Google.com every day, and today, I was typing very fast and typed Googel, and before my mind could process it, I had hit the CTRL + Enter keys.  I expected to have to retype it, but it was redirected to the correct url.  What a great plan.  Knowing that malicious sites would pop up with spellings close to Google, they bought these common misspellings and redirect them.  Other sites could learn from them.  Check out these sites:


http://www.gogle.com
http://www.gooogle.com
http://www.googel.com