使用TypeForwardedToAttribute的正确方法是什么?

时间:2010-12-29 10:57:47

标签: c# .net attributes

我在this postthis one中遇到了此属性。当我们需要升级旧系统时,它似乎非常有用。然后我创建一个测试解决方案(其中包含3个项目)以使用此属性。首先是一个名为“Animal”的类库项目。

namespace Animal
{
   public class Dog
   {
      public static string Name = "old version";
   }
}

然后我创建一个控制台应用程序项目,添加“Animal”作为参考,并使用Main方法:

Console.WriteLine(Animal.Dog.Name);

现在它打印“旧版本”。大!现在我开始“升级”现有项目。我删除了“Animal”中的类Dog,添加了另一个名为“AdvancedAnimal”的类库项目,其中包含:

namespace Animal
{
   public class Dog
   {
      public static string Name = "new version";
   }
}

在“Animal”中添加“AdvancedAnimal”作为参考。此外,通过添加:

来修改“动物”的AssemblyInfo.cs
[assembly: TypeForwardedTo(typeof(Animal.Dog))]

从使用此属性开始,从现在开始,所有Animal.Dog都会转发到“AdvancedAnimal”中的Dog类(实际上Animal中没有Dog类了。我重新编译整个解决方案,并希望控制台应用程序打印“新版本”。但它给了我一个编译错误:

The type name 'Dog' could not be found in the namespace 'Animal'. This type has been forwarded to assembly 'AdvancedAnimal, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' Consider adding a reference to that assembly.

哦,我被告知要添加“AdvancedAnimal”作为我的控制台应用程序的参考!但是,如果我这样做,我不再需要该属性,因为如果我在控制台应用程序中添加“AdvancedAnimal”作为参考,当然Animal.Dog引用“AdvancedAnimal”中的一个!我期望修改“Animal”,添加“AdvancedAnimal”,没有必要更改所有其他项目/类库,因为程序集信息已经提供了足够的信息。升级系统时非常方便。否则,我有20个项目引用“动物”,我需要添加“AdvancedAnimal”作为所有这些项目的参考。更重要的是,我在这个解决方案中找不到任何“TypeForwardedToAttribute”的用法,删除它并不重要。你能告诉我我的测试/想法有什么问题吗?

2 个答案:

答案 0 :(得分:9)

通过MSDN

  

使用TypeForwardedToAttribute   属性从一个移动类型   装配到另一个而不会中断   针对旧编译的调用者   组装

但是你要做的是将类型从同一个程序集转发到同一个程序集中的另一个类型。它没有任何意义。

让我们说清楚。假设你在程序集oldAssembly.dll中有一个类狗

namespace Animal
{
   public class Dog
   { 
      public void printName() {      
           console.writeline("old version");
      }
   }
}

并在其他程序集(x.dll)中引用它

   Dog dg=new Dog();
   dg.printName()

稍后你想要更改printName功能,但不要触及调用者(x.dll)(假设dll已部署且不想被触摸)

所以你创建了一个新的程序集(dll),它得到了

namespace AdvancedAnimal 
{
   public class Dog
   { 
      public void printName() {      
           console.writeline("new version");
      }
   }
}

现在,您现在可以通过添加对新dll的引用并添加

来重新编译旧的dll
[assembly:TypeForwardedTo(typeof(AdvancedAnimal.Dog))]

现在无论对Animal.Dog的调用都转发到AdvancedAnimal.Dog。

所以

  

!我期望的是修改   “动物”,添加“AdvancedAnimal”,没有   必须改变所有其他   项目/类库因为   装配信息已经足够了   信息。这真的很方便   升级系统时。否则,我   有20个项目参考   “动物”,我需要补充一下   “AdvancedAnimal”作为所有人的参考   他们。

您不必为所有20个项目添加AdvancedAnimal。您所要做的就是将AdvancedAnimal添加到Animal。

希望这可以澄清它可能有用的背景

修改

  

我重新编译了整个解决方案   希望控制台应用程序打印   “新版本”。但它给了我一个   编译错误:

我们可以在不修改调用者的情况下调用新程序集。您不应该重新编译整个解决方案,因为您的调用者仍然指向旧程序集中的方法。这就是为什么你得到错误

  

找不到类型名称“狗”   在命名空间'Animal'中。这个类型   已转发到汇编   “AdvancedAnimal

重新编译您的旧版和旧版新组合并将其放入调用者bin并运行exe。它会像魅力一样工作

答案 1 :(得分:1)

这是我第一次听说这个属性,有趣的是:)

我阅读文档的方式,该属性可用于您只提供一组库DLL的场景。

假设您有一些应用程序,它使用DLL中的一组小部件。稍后,您决定将该DLL的一部分移动到单独的DLL中。使用TypeForwardedToAttribute,您可以通过让旧DLL引用新的DLL来实现。您现在可以将两个DLL部署到现有应用程序的安装,而无需重新编译应用程序本身

这在您无法控制应用程序本身但只提供一组库DLL的场景中非常有用。为了让您的代码库继续前进,您可以使用TypeForwardedToAttribute,让用户安全地将其部署到他们的应用程序中,而不会破坏任何内容。