繁体   English   中英

从引用的程序集自动生成main方法

[英]Auto-generate main method from referenced assembly

我正在编辑我的问题,我认为这有点令人困惑,并不能解释我的意图。

编辑:

我的目标是当我的HelloWorld应用程序引用MyClassLibrary我的代码不会编译,所以我确保在运行main方法之前初始化一些代码。 有点像一个类的构造函数。 当我引用MyClassLibrary我想在运行HelloWorld应用程序的main方法之前运行一些代码。 NUnit具有类似的功能。 当我的HelloWorld应用程序引用NUnit时,我收到错误: Error CS0017 Program has more than one entry point defined. Compile with /main to specify the type that contains the entry point. Error CS0017 Program has more than one entry point defined. Compile with /main to specify the type that contains the entry point. 正如@Alex指出的那样,NUnit创建的Main方法是自动生成的。 我想用一些自定义代码自动生成一个main方法。 我怎么能从MyClassLibrary那样做而不在我的HelloWorld应用程序上做任何事情就像NUnit一样呢?


老问题:

我想执行与NUnit测试执行相同的行为,以防止使用Main方法。 在这种情况下,我需要的错误是一件好事。 让我解释一下我的意思。

  1. 我创建了一个针对.net core的hello world应用程序

项目文件:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp2.1</TargetFramework>
  </PropertyGroup>

</Project>

代码文件:(默认hello world c#代码)

  1. 如果我然后运行该应用程序它运行正常

  2. 添加对NUnit的引用,我的项目文件现在包含。

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp2.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="NUnit" Version="3.12.0" />
    <PackageReference Include="NUnit3TestAdapter" Version="3.13.0" />
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
  </ItemGroup>

</Project>    
  1. 当我尝试编译项目时,我收到错误:

错误CS0017程序定义了多个入口点。 使用/ main编译以指定包含入口点的类型。

这意味着还有另一种Main方法。 该方法可能位于我引用的NUnit nuget包中。 这是我试图复制的错误!


现在这是我尝试复制相同错误的方式:

  1. 我删除了在我的hello world应用程序中没有引用NUnitNUnit nugget包。

  2. 使用以下代码创建Project ClassLibrary1

public class MyLib
{
    static void Main()
    {
        Console.WriteLine("fooooo");
        // do something
    }
}
  1. 让我的hello world应用程序引用该项目:

在此输入图像描述

当我编译时,即使有2个Main方法,我也没有错误!

NUnit如何设法阻止使用Main方法? 我怎样才能复制相同的行为? 我想创建一个程序集,在引用它时会阻止执行Main方法。

  • 它只是Microsoft.NET.Test.Sdk使构建失败。
  • <GenerateProgramFile>false</GenerateProgramFile><PropertyGroup>使其无论如何都可以编译和工作。
  • 但是在应用程序中添加另一个带有static void Main类会使构建失败,无论<GenerateProgramFile>
  • 在您的示例中,构建失败,因为Microsoft.NET.Test.Sdk在编译之前向您的应用程序添加了一些自动生成的代码。 该代码位于...\\.nuget\\packages\\microsoft.net.test.sdk\\16.2.0\\build\\netcoreapp1.0\\Microsoft.NET.Test.Sdk.Program.cs 这是另一个Main课程:

// <auto-generated> This file has been auto generated. </auto-generated>
using System;
[Microsoft.VisualStudio.TestPlatform.TestSDKAutoGeneratedCode]
class AutoGeneratedProgram {static void Main(string[] args){}}

顺便说一下Main方法放在另一个程序集中是绝对合法的 你不能在一个exe中拥有2个Main 但你可以在dll中有这样的任意数量:

public class Class1
{
    public static void Main() { }

    public static void Main(string[] args) { }
}

public class Class2
{
    public static void Main() { }

    public static void Main(string[] args) { }
}

它汇编。


更新:

我找到了解决方案。 这都是关于安装nuget ,而不仅仅是添加引用。

  1. 创建一个.NET Core Class Library并将其命名为MyCoreLib
  2. 添加MyCoreClass

namespace MyCoreLib
{
    public static class MyCoreClass
    {
        public static void Initialize()
        {
            System.Console.WriteLine("Initialized from 'MyCoreLib'");
        }
    }
}

  1. 建立图书馆。
  2. 创建以下文件结构:

├───nuget
└───src
    │   MyCoreLib.nuspec
    │
    ├───build
    │   └───netcoreapp2.1
    │           ForcedEntryPoint.cs
    │           MyCoreLib.targets
    │
    └───lib
        └───netcoreapp2.1
                MyCoreLib.dll

MyCoreLib.nuspec

<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
  <metadata>
    <id>MyCoreLib</id>
    <version>1.0.0</version>
    <authors>MyCoreLib</authors>
    <owners>MyCoreLib</owners>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <description>Some description here</description>
    <dependencies>
      <group targetFramework=".NETCoreApp2.1" />
    </dependencies>
  </metadata>
</package>

ForcedEntryPoint.cs

//╔════════════════════════════════════╗
//║ This code was added automatically. ║
//║    Do not change or remove it.     ║
//╚════════════════════════════════════╝
public static class ForcedEntryPoint
{
    public static void Main(string[] args)
    {
        MyCoreLib.MyCoreClass.Initialize();
    }
}

MyCoreLib.targets

<Project InitialTargets="ForceEntryPoint" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
  </PropertyGroup>
  <PropertyGroup>
    <ForcedEntryPoint Condition="'$(ForcedEntryPoint)' == ''">$(MSBuildThisFileDirectory)ForcedEntryPoint$(DefaultLanguageSourceExtension)</ForcedEntryPoint>
    <ForceEntryPoint Condition="'$(ForceEntryPoint)' == ''">true</ForceEntryPoint>
  </PropertyGroup>
  <Target Name="ForceEntryPoint" Condition="'$(ForceEntryPoint)' == 'true'">
    <ItemGroup>
      <Compile Include="$(ForcedEntryPoint)"/>
    </ItemGroup>
  </Target>
</Project>

  1. 使用NuGet Commandline构建这样的包:

D:\nugetwalkthrough\nuget>D:\nugetwalkthrough\nuget.exe pack D:\nugetwalkthrough\src\MyCoreLib.nuspec

  1. 创建一个.NET Core Console App并确保它可以正常工作。
  2. 安装创建的包。
  3. 尝试运行该应用程序并获取错误:

    CS0017程序定义了多个入口点。 使用/ main编译以指定包含入口点的类型。

  4. 从应用程序中删除Main方法,运行它并看到它Initialized from 'MyCoreLib'打印Initialized from 'MyCoreLib'
  5. Main方法放回应用程序并更改项目文件,以便<PropertyGroup>包含<ForceEntryPoint>false</ForceEntryPoint>
  6. 现在它编译并打印Hello World! 来自它自己的Main方法。
  7. <ForceEntryPoint>更改为true会使其再次使用另一个入口点(而不是其中一个入口点)。

我想你应该学习如何在同一个解决方案下制作多个项目。 所以helloworld是主要项目。 然后创建新的测试项目helloworld.test作为测试项目使用在那里添加对NUnit的引用。 现在一切正常,你可以将你的启动项目改为helloworld.test并调试或从visual studio或命令行运行它。 无论如何,我从未在专业编码的主项目中看到过测试项目。 可以用于测试我们评论主要方法并运行测试用例。 测试项目也是可执行的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM