Click here to Skip to main content
Click here to Skip to main content

Forwarding a type from one assembly to another: TypeForwardedToAttribute

By , 23 Mar 2010
Rate this:
Please Sign up or sign in to vote.

Introduction

If you want to move a type from one assembly to another without disrupting callers that compiled against the old assembly, then you should use the TypeForwardedToAttribute attribute.

Background

The scenario is you have an application which has a project which has the details of an employee like manager, clerk, and house-keeping, and you have successfully deployed the application, but some time down the line, it was realized that the HouseKeeping class is best suited under the Vendor category which is in another project (DLL). We can make the changes in the code of Employee which is in another project (DLL) to the Vendor class and just use the TypeForwardedToAttribute to avoid re-building the application and re-deploying it. We just build the respective project and use the DLL, except the main hosting application, and the trick works.

Using the code

Step 1: Creating an assembly

The first step is to create an assembly that has the sample type named Employee. The Employee class has several methods named Display, DisplayClerk, and DisplayHouseKeeping, which display some information.

To create the assembly
  1. Create an empty solution named "TypeForwardedToAttribute_First" and add to it a "Class Library Project" named "Employee.cs".
  2. Note: Please delete Class1.cs from the "TypeForwardedToAttribute_First" project if it is created automatically. We don't need it.

  3. Add a class named "Employee" to the "TypeForwardedToAttribute_First" project and modify its code as below:
  4. using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Runtime.CompilerServices;
    using TypeForwardedToAttribute_First;
    
    namespace TypeForwardedToAttribute_First
    {
        public class HouseKeeping
        {
            public void DisplayHouseKeeping()
            {
                Console.WriteLine("HouseKeeping Class");
            }
        }
    
        /// <summary>
        /// This is a Manager Class
        /// </summary>
        public class Manager : Employee
        {
            /// <summary>
            /// This Method will display details about Manager
            /// </summary>
            public void Display()
            {
                Console.WriteLine("Manager Class");
            }
        }
    
        public class Clerk : Employee
        {
            /// <summary>
            /// This Method will display details about Clerk
            /// </summary>
    
            public void DisplayClerk()
            {
                Console.WriteLine("Clerk Class");
            }
        }
    
        public class Employee
        {
            static void Main(string[] args)
            {
                Console.WriteLine("Trainee Class Will be Moved");
            }
            /// <summary>
            /// This is a main Method will display details about Manager,Clerk,Trainee
            /// </summary>
    
            public static void Display()
            {
            }
        }
    }
  5. Now you can build the TypeForwardedToAttribute_First project, which produces TypeForwardedToAttribute_First.dll in its output folder.

Step 2: Creating a host application

The next step is to create an application for hosting Employee. Creating a "Console Application" is the simplest way which satisfies Employee hosting.

To create the host application
  1. Add a "Console Application" project named "TypeForwardedToAttribute" to the solution.
  2. Add a reference from the TypeForwardedToAttribute_First project to the TypeForwardedToAttribute project.
  3. Modify the Program class as below:
  4. /*The purpose of this Source code is to make
    * the Concept of TypeForwardedToAttribute crystal clear 
    * SHORT DESCRIPTION -The scenario is you have an application
    * which have a Project which  have the Details
    * of an Employee like Manager ,Clerk and House keeping,
    * and you have successfully deployed the application ,but some time down the 
    * line it was ralized that the HouseKeeping Class is BestSuited
    * Under Vendor Category which is in another project(dll) 
    * then we can make the changes in the Code of Employeee
    * which is in another project(dll) to the Vendor Class
    * and just use  the TypeForwardedToAttribute to avoid
    * the re-building of an applicatioon and re-deploying it
    * we just build the respective project and use there dll except
    * the main hosting application and the trick works 
    * Thumb Rule-Only use is when you have some legacy application
    * (no source available, or cannot recompile for any other reason) 
    * referencing the type T1 originally located in A1 and for whatever
    * reason you need to move the type out from that
    * assembly.Then you can use the concept of TypeForwardedToAttribute
    * and you'll have your type happily moved out 
    * of A1 to A2, legacy binary still referencing the A1,
    * but using type T1 from A2.At least that's the reason for 
    * the attribute from my understanding
    * 
    * 
    */
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using TypeForwardedToAttribute_First;
    /* VERY IMPORTANT NOTE: Don't build the TypeForwardedToAttribute
     * project again here elsewhere you will 
     * get a compiler error because of following rule.
     * RULE: Forwarded types can't be referenced.*/
    namespace TypeForwardedToAttribute
    {
        class Program
        {
            static void Main(string[] args)
            {
                Console.WriteLine("Please understand the Type Forwarding Concept");
                Clerk objClerk = new Clerk();
                Manager objManager = new Manager();
                HouseKeeping objHouseKeeping = new HouseKeeping();
    
    
                objClerk.DisplayClerk();
                objManager.Display();
                objHouseKeeping.DisplayHouseKeeping();
                Employee.Display();
                Console.ReadLine();
            }
        }
    }
  5. Set the TypeForwardedToAttribute project as the "Startup Application" and run the solution. You will see that ExampleType presents itself like below:
  6. Please understand the Type Forwarding Concept
    Clerk Class
    Manager Class
    HouseKeeping Class

Step 3: Creating a new assembly

The next step is to create a new assembly which will be the destination of moving the HouseKeeping type. Consider that you have deployed TypeForwardedToAttribute to several users and now you need to update Employee, i.e., removing the HouseKeeping class from it, but you don't want to disrupt the deployed application. In this condition, you should create a new assembly and move the type to it. Then you should copy both assemblies to the deployed application folder.

To create the new assembly
  1. Add a "Class Library" named "TypeForwardedToAttribute_Second" to the solution.
  2. Note: Please delete Class1.cs from the TypeForwardedToAttribute_Second project if it is created automatically. We don't need it.

  3. Add a class named "Vendor" to the TypeForwardedToAttribute_Second project and modify its code as below.
  4. Very important note: By default, the added class will be in the TypeForwardedToAttribute_Second namespace, but you must rename its namespace name to TypeForwardedToAttribute_First because of the following rule.

    Rule: The original type and the forwarded type must be in the same namespace.

    Let's see the HouseKeeping declaration in the TypeForwardedToAttribute_Second project.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    /*The name space is modified from TypeForwardedToAttribute_First
     *to TypeForwardedToAttribute_Second as this is must for TypeForwarding 
     *to attribute as the Rule says:"The original type and the forwarded type
     *must be in a same namespace."*/
    namespace TypeForwardedToAttribute_First
    {
    
    
        public class HouseKeeping
        {
            public void DisplayHouseKeeping()
            {
                Console.WriteLine("HouseKeeping Class from Vendor");
            }
        }
    
        /// <summary>
        /// Main Vendor Class
        /// </summary>
        public class Vendor
        {
            static void Main(string[] args)
            {
            }
        }
    }

Step 4: Moving the type

The next step is to move HouseKeeping to its destination: TypeForwardedToAttribute_Second.

To move the type
  1. Add a reference from the TypeForwardedToAttribute_Second project to the TypeForwardedToAttribute_First project.
  2. Comment the HouseKeeping declaration in the TypeForwardedToAttribute_First project and add a TypeForwardedToAttribute attribute instead, as below:
  3. using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Runtime.CompilerServices;
    using TypeForwardedToAttribute_First;
    
    /*Need to refer using System.Runtime.CompilerServices*/
    [assembly: TypeForwardedTo(typeof(HouseKeeping))]
    namespace TypeForwardedToAttribute_First
    {
        /* This HouseKeeping class is moved to TypeForwardedToAttribute_Second*/
        //public class HouseKeeping
        //{
        //    public void DisplayHouseKeeping()
        //    {
        //        Console.WriteLine("HouseKeeping Class");
        //    }
        //}
    
        
        /// <summary>
        /// This is a Manager Class
        /// </summary>
        public class Manager : Employee
        {
            /// <summary>
            /// This Method will display details about Manager
            /// </summary>
            public void Display()
            {
                Console.WriteLine("Manager Class");
            }
        }
    
        public class Clerk : Employee
        {
            /// <summary>
            /// This Method will display details about Clerk
            /// </summary>
    
            public void DisplayClerk()
            {
                Console.WriteLine("Clerk Class");
            }
        }
    
        public class Employee
        {
            static void Main(string[] args)
            {
                Console.WriteLine("Trainee Class Will be Moved");
            }
            /// <summary>
            /// This is a main Method will display details about Manager,Clerk,Trainee
            /// </summary>
    
            public static void Display()
            {
            }
        }
    }

Very important note: Don't build the TypeForwardedToAttribute project again here, else you will get a compiler error because of the following rule:

Rule: Forwarded types can't be referenced.

Applying the moved type to the host

The final step is to apply the new type to the deployed host.

To apply the moved type

  1. Build the TypeForwardedToAttribute_Second project first and then build the TypeForwardedToAttribute_First project.
  2. Copy and replace TypeForwardedToAttribute_First.dll beside TypeForwardedToAttribute.exe.
  3. Copy TypeForwardedToAttribute_Second.dll beside TypeForwardedToAttribute.exe too.
  4. Double click TypeForwardedToAttribute.exe. You will see that HouseKeeping presents itself like:
  5. Please understand the Type Forwarding Concept
    Clerk Class
    Manager Class
    HouseKeeping Class from Vendor

As you can see, it tell us that it is from type ForwardedToAttribute_Second. Yes, the job is done.

The Limitation

The .NET Framework version 2.0 does not allow type forwarding from assemblies written in Visual Basic. However, a Visual Basic application can consume forwarded types if it uses assemblies coded in C# or C++.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Ashish Kumar Mukherjee
Web Developer Accenture Service
India India
Software Professional having 8 years of experience in software development/design, requirement, testing and implementation using .NET Technologies(C#, ASP.NET,WPF,WCF,MVC), SQL Server 2005/2008, Sybase, DB2, Windows XP, 2000, Cruise Control and basic idea of Remedy.

Comments and Discussions

 
-- There are no messages in this forum --
| Advertise | Privacy | Mobile
Web02 | 2.8.140415.2 | Last Updated 24 Mar 2010
Article Copyright 2010 by Ashish Kumar Mukherjee
Everything else Copyright © CodeProject, 1999-2014
Terms of Use
Layout: fixed | fluid