AssemblyInfo 用法文档
下面这篇可以直接当作说明文档使用。
AssemblyInfo 使用说明文档
1. AssemblyInfo 简介
AssemblyInfo 是 .NET 项目中用于声明程序集级元数据的配置文件,常见文件名为:
AssemblyInfo.cs
它的作用是描述程序集本身的信息,而不是某个类或方法的信息。
常见用途包括:
- 定义程序集名称相关信息
- 设置版本号
- 声明 COM 可见性
- 设置 GUID
- 声明友元程序集
- 进行类型转发
在传统 .NET Framework 项目中,AssemblyInfo.cs 常放在 Properties 目录下。
在较新的 SDK 风格项目中,很多程序集属性也可以在 .csproj 中直接配置,部分内容会自动生成。
2. 常见的 AssemblyInfo 配置项
2.1 基本信息
using System.Reflection;
[assembly: AssemblyTitle("CoreDevice")]
[assembly: AssemblyDescription("设备通信组件")]
[assembly: AssemblyCompany("XXX Company")]
[assembly: AssemblyProduct("CoreDevice Suite")]
[assembly: AssemblyCopyright("Copyright © XXX")]
作用:
-
AssemblyTitle:程序集标题 -
AssemblyDescription:程序集说明 -
AssemblyCompany:公司名称 -
AssemblyProduct:产品名称
2.2 版本信息
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
区别:
-
AssemblyVersion:程序集版本,影响程序集绑定 -
AssemblyFileVersion:文件版本,主要给 Windows 文件属性显示 -
AssemblyInformationalVersion:产品展示版本,可带说明文字
说明:
- 如果随意修改
AssemblyVersion,可能影响旧项目引用 - 一般发布时更常调整
AssemblyFileVersion和AssemblyInformationalVersion
2.3 COM 可见性
using System.Runtime.InteropServices;
[assembly: ComVisible(false)]
[assembly: Guid("12345678-abcd-1234-abcd-1234567890ab")]
作用:
-
ComVisible(false):默认不对 COM 暴露类型 -
Guid:如果程序集需要 COM 互操作,会用到 GUID
2.4 友元程序集
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("CoreDevice.Tests")]
作用:
- 让指定程序集访问当前程序集中的
internal成员 - 常用于单元测试项目访问内部实现
3. TypeForwardedTo 的作用
3.1 基本概念
TypeForwardedTo 用来声明:
当前程序集不再直接定义某个类型,而是把这个类型转发到其他程序集。
示例:
using System.Runtime.CompilerServices;
[assembly: TypeForwardedTo(typeof(CoreDevice.Device.ModbusRTU))]
这表示:
-
ModbusRTU这个类型的实际定义不在当前程序集 - 运行时会去真正包含该类型的程序集里查找
3.2 为什么要使用 TypeForwardedTo
典型场景:
-
程序集拆分
- 原来所有代码都在一个 DLL
- 后来拆成多个 DLL,按模块管理
-
重构迁移
- 把某些类型迁移到新的类库中
- 但又希望旧代码尽量不受影响
-
兼容老版本
- 老项目仍引用旧程序集
- 新版本通过类型转发减少升级成本
3.3 你的示例说明
例如:
[assembly: TypeForwardedTo(typeof(CoreDevice.Device.Execute))]
[assembly: TypeForwardedTo(typeof(CoreDevice.Device.ModbusRTU))]
[assembly: TypeForwardedTo(typeof(CoreDevice.LibModbus.Modbus))]
说明这些类型:
ExecuteModbusRTUModbus
虽然从逻辑上仍属于原有对外 API 的一部分,
但它们的实际代码实现已经放到了其他程序集。
这通常用于:
- 保持旧接口兼容
- 支持模块化拆分
- 降低老项目迁移成本
4. TypeForwardedTo 使用示例
4.1 原始情况
原来所有类型都在 OldLibrary.dll 中:
namespace Demo
{
public class DeviceHelper
{
}
}
4.2 重构后
把 DeviceHelper 挪到 NewLibrary.dll 中实现。
此时为了兼容旧引用,可以在原程序集里增加:
using System.Runtime.CompilerServices;
[assembly: TypeForwardedTo(typeof(Demo.DeviceHelper))]
这样:
- 老项目引用
OldLibrary.dll - 实际类型定义在
NewLibrary.dll - CLR 通过转发找到真正实现
5. 使用 TypeForwardedTo 的注意事项
5.1 必须保证目标程序集可用
如果只写了转发,但运行时找不到真正实现该类型的 DLL,就会报错。
5.2 类型不能在两个地方重复定义
同一个完整类型不能既在当前程序集定义,又被转发,否则会冲突。
5.3 更适合“迁移兼容”,不适合滥用
TypeForwardedTo 主要用于:
- 程序集拆分
- 历史兼容
不建议把它当作日常开发中的普通组织方式。
5.4 命名空间不变更时更容易兼容
如果迁移时连命名空间、程序集结构都大改,兼容成本会更高。
6. 现代 .NET 项目中的变化
在 .NET Core / .NET 5+ / SDK 风格项目中:
- 很多程序集属性可直接写在
.csproj -
AssemblyInfo.cs不一定手工维护 - 但像
TypeForwardedTo、InternalsVisibleTo这类特性,仍然常常手工写在.cs文件中
例如 .csproj 中可写:
<PropertyGroup>
<AssemblyTitle>CoreDevice</AssemblyTitle>
<Version>1.0.0</Version>
<Company>XXX Company</Company>
</PropertyGroup>
7. 适合在项目中保留的 AssemblyInfo 内容
一般建议保留这些内容:
- 版本信息
- 产品信息
InternalsVisibleToComVisibleGuidTypeForwardedTo
如果项目是 SDK 风格并且自动生成程序集信息,则应避免和自动生成项重复,防止编译报重复特性错误。
8. 总结
AssemblyInfo 的本质是:
定义程序集级别的元数据和行为。
而你这段 CoreDevice 代码中的 TypeForwardedTo,本质是:
为了程序集拆分或重构后仍兼容旧代码,把类型访问转发到新的实现程序集。
它的核心价值在于:
- 保持兼容
- 降低升级成本
- 支持模块化拆分
你这段 AssemblyInfo 里的内容,核心作用是:
把类型从旧程序集“转发”到新程序集。
也就是说,外部项目原来可能引用的是某个旧 DLL,但这些类型实际上已经被挪到了别的 DLL 里。通过 TypeForwardedTo,CLR 运行时会知道:
- 这个类型虽然名字还属于原来的程序集对外契约
- 但真正实现已经在另一个程序集里
- 这样可以尽量不改调用方代码,保持兼容
你贴的这些代码例如:
[assembly: TypeForwardedTo(typeof(CoreDevice.Device.Execute))]
[assembly: TypeForwardedTo(typeof(CoreDevice.Device.ModbusRTU))]
[assembly: TypeForwardedTo(typeof(CoreDevice.LibModbus.Modbus))]
表示这些类型已经不在当前程序集里直接实现,而是被“转发”到实际定义它们的程序集。
一、这些内容具体是干吗用的
1. AssemblyInfo 是什么
AssemblyInfo.cs 通常用来放程序集级别的元数据,例如:
- 程序集标题
- 版本号
- 公司信息
- COM 可见性
- GUID
- 类型转发信息
以前传统 .NET Framework 项目里,这些内容很多都写在 Properties/AssemblyInfo.cs 中。
2. TypeForwardedTo 是什么
TypeForwardedTo 是程序集级别特性,作用是:
- 告诉运行时:某个类型已经移动到别的程序集
- 保持旧版本 API 的兼容性
- 减少因为拆分 DLL、重构命名空间/程序集导致的引用崩溃
3. 你的场景里意味着什么
你这个 CoreDevice 的写法,大概率说明项目做过这类调整:
- 以前某些类型在
CoreDevice主程序集里 - 后来把实现拆到了
CoreDevice.Device、CoreDevice.LibModbus等模块 - 为了不让老项目全部改引用,就在原程序集里加
TypeForwardedTo
这样老代码如果还写:
using CoreDevice.Device;
或者还引用老 DLL,很多情况下仍然能工作。