Zuhaib

A very lazy but meticulous blogger

.NET Type Forwarding – Moving Types Between Assemblies

with 9 comments

I learned about this really cool feature in the .NET framework while reading an MS certification book, and could not stop blogging about it. Type forwarding in .NET allows you to move type from one assembly to another without recompiling applications that use the old assembly.

Important Notes:

  1. Microsoft Visual Basic 2005 does not support the use of the TypeForwardedToAttribute attribute to forward types written in Visual Basic 2005. Applications written in Visual Basic 2005 can use forwarded types written in other languages.
  2. The compilers do not support forwarding generic types in .NET 2.0, 3.0 and 3.5. Support for this was added in .NET 4.0.

For this example, I would write one assembly called Animal that would contain a class called Dog, which would be consumed by an application called Consumer1. Later, I would move the Dog class to a new assembly called Canine, and we would see how we can make the Consumer1 application still work using .NET type forwarding feature.

Animal (Class Library)

As discussed here is the Dog class that would reside inside the Animal assembly.

Dog.cs

namespace Animal
{
    using System;
    public class Dog
    {
        /// <summary>
        /// Make the dog bark.
        /// </summary>
        public void Bark()
        {
            Console.WriteLine("Arrgh.... Woof Woof!");
        }
    }
}

It’s a very simple class that contains a public method called Bark, which would output "Arrgh…. Woof Woof!" to the console when invoked.

Consumer1 (Console Application)

I would now write our first application that would consume the animal assembly. Its a simple console application that has reference to the Animal assembly.

namespace Consumer1
{
    using System;
    using Animal;
    /// <summary>
    /// The program.
    /// </summary>
    internal class Program
    {
        #region Methods
        /// <summary>
        /// The entry point.
        /// </summary>
        /// <param name="args">
        /// The command line arguments.
        /// </param>
        private static void Main(string[] args)
        {
            Console.WriteLine("Consumer 1 Application");
            Dog dog = new Dog();
            dog.Bark();
            Console.ReadKey();
        }
        #endregion
    }
}

In the main method of the Consumer1 application I have created an instance of the Dog class and then called its Bark method. When we run this application we would get the following output.

Output:

Consumer 1 Application

Arrgh…. Woof Woof!

Canine (Class Library)

I moved the Dog class from Animal assembly to the new assembly called Canine.

namespace Animal
{
    using System;
    public class Dog
    {
        /// <summary>
        /// Make the dog bark.
        /// </summary>
        public void Bark()
        {
            Console.WriteLine("Arrgh.... Woof Woof! (Inside New Assembly)");
        }
    }
}

The only difference in the class definition here, is the text that I output to the console when the Bark method is invoked. I have changed it so that we can easily spot out that our old application (Consumer1) is accessing the Dog class from the new Canine assembly.

Also you might wonder, if the assembly name is Canine then why is the namespace for the Dog class still Animal? It’s necessary to keep the old namespaces while moving types between assemblies for the old applications to find the type in the new assembly.

If we deploy the Animal assembly without the Dog class then existing installed applications that were compiled against the old Animal assembly would break. Unless, we use type forwarding in the modified Animal assembly and let it know where to look for the Dog class when its requested. To enable type forwarding we need to do the following things:

  1. Add a reference of the new Canine assembly to the Animal assembly.
  2. Add the TypeForwardedToAttribute attribute to the animal assembly and specify the type to be forwarded.

Normally we add all assembly attributes to the AssemblyInfo.cs file. The TypeForwardedToAttribute attribute resides in the System.Runtime.CompilerServices namespace. Add the following line to the AssemblyInfo.cs.

using System.Runtime.CompilerServices;

// Type forward the dog class to the Canine assembly
[assembly: TypeForwardedTo(typeof(Animal.Dog))]

When any application would look for the Dog class in the Animal assembly it would be forwarded to the Canine assembly. Now when we deploy the new Animal & Canine assembly though the Consumer1 application does not have a reference to the Canine assembly, it would still find the Dog class and produce the following output.

Output:

Consumer 1 Application

Arrgh…. Woof Woof! (Inside New Assembly)

Deploying both the assemblies are important. Otherwise the Consumer1 application will not find the Dog class, and would crash.

Source Code:

Download the source code accompanying this post here. TypeForwardedToSample.zip

Possible Related Posts:

  1. C# – Change log4net Log Path and Level Programmatically
  2. Writing Provider Independent .NET Data Access Code

Written by Zuhaib

January 4th, 2010 at 3:22 am

9 Responses to '.NET Type Forwarding – Moving Types Between Assemblies'

Subscribe to comments with RSS or TrackBack to '.NET Type Forwarding – Moving Types Between Assemblies'.

  1. Will this of type type forwarding supported in .NET 3.5?
    Because i got an error will bulding the app that has a reference of two namespaces (with same named classes)with same names but each of them are in assemblies with different names.. as you said..
    please reply me…via email

    [ Reply ]

    sai viswanath

    6 Jan 10 at 3:05 pm

  2. @Sai
    The app has reference to two namespaces with same named class? This example doesn’t say that.

    As said type forwarding is used to move one type from assembly to another. So the type which is used by old applications is no more inside the old assembly. It is moved to the new assembly.

    The old application doesn’t need to recompiled, thats the whole point of Type Forwarding.

    Please check the attached sample source code. The dog class is not present (commented) in the Animal assembly. The Consumer1 application has reference to the Animal assembly alone. Still because we have used type forwarding in Animal assembly, Consumer1 application is able to find the type from the Canine assembly, without having any direct reference to it.

    [ Reply ]

    Zuhaib

    7 Jan 10 at 2:17 am

  3. ok fine, i understood that class names can be different. But my doubt was that whether this type forwading is supported in .NET 3.5 or not. Because i am getting the error as ” Type ‘check1.Hello1′ is defined in this assembly, but a type forwarder is specified for it ”

    where in your application the same type is Animal.Dog

    [ Reply ]

    sai viswanath

    7 Jan 10 at 2:10 pm

  4. Very well explained.

    [ Reply ]

    Zuhaib Reply:

    Glad that it helped.

    [ Reply ]

    Tajdar

    9 Jan 10 at 12:03 pm

  5. @Sai
    The class name cannot be different and the namespaces should be the same.

    The sample that I have uploaded is written in .NET 3.5. Could you upload your sample and post the link here?

    I am going to add source highlighting in comments, then you can directly paste your code here.

    [ Reply ]

    Valentina Reply:

    Hello,
    I have some problem with type forwarding.
    I have downloaded your source code, but it doesn’t compile! It gives me a reference error. I could solve it by adding a reference to the new dll, but doing this I lose the whole point of interest of Type Forwarding. Could you help me?

    [ Reply ]

    Zuhaib Reply:

    As per the example .. The Dog class is no more in the Animal library .. as you can see from the source the Dog class has been commented.

    The whole point of type forwarding is to move the type from one assembly to another without having to recompile the assemblies that consume the type that is being moved.

    In this example, the Consumer1.exe was compiled against Animal library when the definition of Dog class was present in Animal library.

    We then moved the Dog class to Canine library and added TypeForwardedTo attribute to the Animal library for the Dog class.

    The old Consumer1.exe (in the Build folder) that was compiled against the old Animal library would still search for Dog class in Animal library.

    Now if we would not have specified the library containing the Dog class using TypeForwardedTo attribute, the old Consumer1.exe would crash.

    But because we have done the required changes in Animal library, we do not have to compile the Consumer1.exe again.

    I you would want to recompile the Consumer1 project, then obviously you need to add reference to the library containing the Dog class in the Consumer1 project.

    TypeForwardedToAttribute is used to move types from one assembly to another without disrupting callers (which is compiled against the old assembly) at runtime, not compile time.

    Hope this clears ur doubt.

    [ Reply ]

    Valentina Reply:

    Thank you, really helpful!
    Valentina

    Zuhaib

    9 Jan 10 at 12:08 pm

Leave a Reply