C# Visual studio一个项目,输出多个DLL?

C# Visual studio一个项目,输出多个DLL?,c#,visual-studio,C#,Visual Studio,我正在编写一个支持插件的项目。 由于许多插件相对较小(只有一个源文件/类),我希望将它们全部放在visual studio中的一个项目中,但要成功地做到这一点,我需要将每个源文件/类编译成自己的dll文件,使用visual studio可以这样做吗 如果VisualStudio无法做到这一点,那么在仍然使用VisualStudio进行编码和调试的情况下,是否可以使用另一个生成系统 目前,我已将插件项目输出类型设置为console,并编程了一个main()方法,该方法将把源目录中的所有.cs文件编

我正在编写一个支持插件的项目。 由于许多插件相对较小(只有一个源文件/类),我希望将它们全部放在visual studio中的一个项目中,但要成功地做到这一点,我需要将每个源文件/类编译成自己的dll文件,使用visual studio可以这样做吗

如果VisualStudio无法做到这一点,那么在仍然使用VisualStudio进行编码和调试的情况下,是否可以使用另一个生成系统

目前,我已将插件项目输出类型设置为console,并编程了一个main()方法,该方法将把源目录中的所有.cs文件编译为DLL,并将它们复制到正确的目录中。然后我将该控制台应用程序设置为插件项目的构建后事件。它是有效的,但看起来像是一个非常丑陋的黑客

使用visual studio 2010。

您只需添加所需数量的项目即可


您可以拥有5个类库项目并编译它们,生成5个DLL。

如果您希望每个代码文件都是自己的DLL,那么您必须为每个代码文件创建一个新项目。但您可以将多个项目文件(.csproj)放入一个大型解决方案中


如果这不适合您,那么您可以始终使用命令行编译项目。这将允许您自定义构建以满足您的需要。例如,您可以编写一个批处理脚本或powershell脚本,将所有代码文件编译成一个单独的DLL。

您可以为每个插件创建一个项目,并将所有项目分组到一个解决方案中

如果不希望每个插件都有一个项目,可以使用

如何为每个插件文件生成dll
  • 在项目中添加所有插件文件

  • 编辑项目文件以指定哪个类将生成插件库:

    <ItemGroup>
      <Compile Include="Class1.cs">
        <Plugin>true</Plugin>
      </Compile>
      <Compile Include="Class2.cs" />
      <Compile Include="Class3.cs">
        <Plugin>true</Plugin>
      </Compile>
      <Compile Include="Program.cs" />
      <Compile Include="Properties\AssemblyInfo.cs" />
    </ItemGroup>
    
    
    真的
    真的
    
  • 在项目文件中添加新目标以生成插件库

    <Target Name="BuildPlugins">
      <CSC Condition="%(Compile.Plugin) == 'true'"
           Sources="%(Compile.FullPath)"
           TargetType="library"
           OutputAssembly="$(OutputPath)%(Compile.FileName).dll"
           EmitDebugInformation="true" />
    </Target>
    
    
    
  • 如果要在每次生成后创建插件库,请添加生成后目标:

    <Target Name="AfterBuild" DependsOnTargets="BuildPlugins">
    </Target>
    
    
    

  • 为了扩展上面Julien Hoarau的回答,这里有一个解决方案,允许您从单个项目中编译多个DLL文件,并让这些DLL文件从多个CS文件编译。只需打开csproj文件并将其添加到标记之前:

    
    假的
    假的
    假的
    假的
    假的
    假的
    假的
    假的
    
    这是我的方法-它让您将所有内容组织在底部,而不是分散在整个项目文件中。使用

    <InProject>false</InProject>
    
    false
    
    允许我们对SolutionExplorer隐藏文件,并有一个单独定义的文件列表,而不是简单地将插件标记添加到我们想要的文件中。在主解决方案中,确保在插件中编译的所有文件上都将构建操作设置为“无”,以便主项目文件中没有重复

    更多关于CSC的阅读:

    使用csc.exe生成命令行

    使用C#2.0命令行编译器

    Csc任务

    MSBuild条件

    我希望这对某人有用。

    一些诗歌:

    在我的例子中,我需要专门为
    单元测试
    项目构建插件
    dll
    。。如果你用“正常的方式”,通过为每个插件创建单独的项目,那么你最终将拥有比核心程序集更多的与单元测试相关的项目。。所以我认为在某些情况下,在同一个项目中进行多个构建是值得的。话虽如此,我想提供一个被接受答案的改进版本

    新方法的改进:

    • 支持新的
      SDK
      项目(用于.net核心)
    • 支持生成引用解决方案中其他项目的程序集
    创建新的空库项目,确保结构符合以下要求:

    <Project Sdk="Microsoft.NET.Sdk">
      <PropertyGroup>
        <TargetFramework>net472</TargetFramework>
      </PropertyGroup>
    </Project>
    
    这将使手动包含用于生成的文件成为可能。。否则,默认情况下,生成将包括所有文件

    然后显式添加要编译的项:

    <ItemGroup>
    <Compile Include="TestApp1.cs">
      <Plugin>true</Plugin>
    </Compile>
    </ItemGroup>
    
    您可以这样做,如果类文件名包含一个特定的关键字,那么您可以触发对该文件的单独编译。。或者如果文件位于特定文件夹中!在上面的示例中,如果文件中有单词“Plugin”,那么它将被CSC任务拾取。。我建议检查元数据页面以查看所有选项

    奖励:如果您和我一样喜欢能够进入代码并能够输出到
    调试
    输出窗口,您还可以定义:

    我的最新配置如下所示:

      <Target Name="BuildPlugins" AfterTargets="PostBuildEvent">
        <CSC 
          Condition="$([System.Text.RegularExpressions.Regex]::IsMatch('%(Compile.FullPath)', '.*\\AppUnitTests\\Plugins\\.*.cs'))"
          Sources="%(Compile.FullPath)" 
          TargetType="library" 
          References="@(ReferencePath)"
          OutputAssembly="$(OutputPath)Plugins\%(Compile.FileName).dll" 
          EmitDebugInformation="true"
          DefineConstants="DEBUG;TRACE"
          DebugType="full" />
      </Target>
    
    
    
    希望它对某人有用;)


    p、 感谢原作者给出了一个我可以改进的例子。

    是的,但是创建10个项目,每个项目都有一个源文件似乎是一种可怕的浪费,我希望有一种方法可以将一个项目中的所有源文件编译成单独的DLL。对于项目和AssemblyInfo文件来说,可能浪费了几千字节?恕我直言,我们这里说的是虚假经济。这就是项目的目的,将源代码封装到程序集中。:)所以没有适合你的方法!嘿,谢谢你的回答……它解决了我一半的问题。但我想要版本号和其他与这些新生成的dll相关的信息,并且希望将多个文件合并到一个dll中,而不是单个文件。如果有人知道这方面的情况,请帮助我……这对我会有很大的帮助……哦,哦,你从哪里得到这些知识的?太好了,太好了,这正是我想要的结果,是多文件组装吗?C
    <ItemGroup>
    <Compile Include="TestApp1.cs">
      <Plugin>true</Plugin>
    </Compile>
    </ItemGroup>
    
      <Target Name="GatherReferences" DependsOnTargets="ResolveReferences">
        <ItemGroup>
          <MyReferencedAssemblies Include="@(ReferencePath)" />
        </ItemGroup>
      </Target>
    
      <Target Name="TestMessage" AfterTargets="Build" >
        <Message Text="Referenced assemblies: @(ReferencePath)" Importance="high"/>
      </Target>
    
      <Target Name="BuildPlugins" AfterTargets="PostBuildEvent">
        <CSC Condition="%(Compile.Plugin) == 'true'"
             Sources="%(Compile.FullPath)"
             TargetType="library"
             References="@(ReferencePath)"
             OutputAssembly="$(OutputPath)%(Compile.FileName).dll"
             EmitDebugInformation="true" />
      </Target>
    
    Condition="$([System.Text.RegularExpressions.Regex]::IsMatch('%(Compile.Filename)', 'Plugin'))"
    
      DefineConstants="DEBUG;TRACE"
      DebugType="full"
    
      <Target Name="BuildPlugins" AfterTargets="PostBuildEvent">
        <CSC 
          Condition="$([System.Text.RegularExpressions.Regex]::IsMatch('%(Compile.FullPath)', '.*\\AppUnitTests\\Plugins\\.*.cs'))"
          Sources="%(Compile.FullPath)" 
          TargetType="library" 
          References="@(ReferencePath)"
          OutputAssembly="$(OutputPath)Plugins\%(Compile.FileName).dll" 
          EmitDebugInformation="true"
          DefineConstants="DEBUG;TRACE"
          DebugType="full" />
      </Target>