вторник, 20 сентября 2011 г.

Extern alias walkthrough


Extern aliases is a feature that was introduced in VS 2005 that I don’t believe is being used very often. There are two reasons for this.  First, the feature is somewhat undiscoverable, particularly if you don’t happen to be looking for it.  Second, the feature itself is useful in the somewhat narrow scenario of needing to explicitly differentiate between two type names that are identical except for the assembly strong name (name, version, public key, etc.) in which they are defined. 

Of course, if you happen to be in that situation this feature can prove invaluable.  I wrote the walkthrough below while we were developing the feature; it should provide a reasonable starting point for how extern aliases can be used in Visual C#.

  1. Create a C# Class Library called FooVersion1
  2. Replace the template code in Class1.cs with the following:
    using System;

    namespace Acme
    {
        public class Foo
        {
            public void Bar()
            {
                Console.WriteLine("Bar");
            }
        }
 }


  1. Right-click on the solution in solution explorer and select Add | New Project
  2. Save the current project (only applicable in express)
  3. Select a Class Library in the new project dialog and change the project name to FooVersion2 and press OK
  4. Replace the code in Class1.cs with the following:
    using System;

    namespace Acme
    {
        public class Foo
        {
            public void Bar()
            {
                Console.WriteLine("Bar");
            }

            public void Goo()
            {
                Console.WriteLine("Goo");
            }
        }
    }

  1. Right-click on the solution in solution explorer and select Add | New Project
  2. Select a Console Application and call it Consumer
  3. Right-click on Consumer and select ‘Set as startup project’

  1. Right-click on the references node in the Consumer project and select ‘Add Reference’
  2. Click on the projects tab, and multi-select FooVersion1 and FooVersion2
  3. Click OK
  4. Add the following line to Main in the Program type of the Consumer project:
Acme.Foo f = new Acme.Foo();

  1. Build the solution via Ctrl+Shift+B (or F6)
  2. Notice that you get two build errors:

  1. Open solution explorer and select FooVersion1 in the References folder of the Consumer project

  1. Hit F4 (or select View | Properties Window)
  2. Change the Aliases property to FooVersion1

  1. Build the solution
  2. Now everything will build correctly, because Acme.Foo unambiguously refers to FooVersion2
  3. Add the following directive to the top of Program.cs in the Consumer project: 
   extern alias FooVersion1;

  1. Change the usage of Acme.Foo to:
      FooVersion1::Acme.Foo f = new FooVersion1::Acme.Foo();
      f.Bar();

  1. Notice that when you type ‘f.’ the completion list contains only those methods in FooVersion1 of Acme.Foo (notably it does not include Goo)
  2. Build the solution and everything will build correctly
  3. Finally add the following code under f.Bar() in Program.cs of the Consumer project:
      Acme.Foo f2 = new Acme.Foo();
      f2.Goo();

  1. Notice that f2’s completion list contains Goo. 
  2. Build again using Ctrl+Shift+B and notice that there are still no build errors
This shows a usage pattern which we expect to be relatively common when these ambiguities exist.  The assembly which will be used less often will be aliased while the other will continue to exist in the global namespace (such that it doesn’t require qualification through an extern alias).

Комментариев нет: