将 ASP.Net Core 2 (.NET Framework) Web Api 拆分为类库和托管项目是否可能/明智?

2024-02-27

我正在尝试使用 Visual Studio 2017 (v15.4.5) 将现有的 WCF Web API(针对 .NET Framework 4.6.1)移植到 ASP.Net Core 2,但在找出组织项目的良好/通用/受支持的方法时遇到困难,以及它们应该是什么类型的项目。

例如:

  • 服务器和托管的单个项目,or用于托管的服务器和控制台应用程序的类库

  • 用于控制台应用程序的 Windows 经典桌面项目和用于服务器库的(新型 csproj)Web 应用程序,or两个 Web 应用程序(一个输出类库,另一个输出控制台应用程序)

我偷偷怀疑我缺少一些基本的东西,这意味着一种方法应该比其他方法更受青睐,甚至是强制性的,但发现很难从ASP.Net Core 2 文档 https://learn.microsoft.com/en-us/aspnet/core/.

具体要求

  • 应针对 .NET Framework 4.6.1
    由于我需要从 Web API 的内部访问 Windows 注册表,因此我的目标是 .NET Framework 4.6.1 而不是 .NET Core。

  • 使用 HTTP.sys 的主机
    我打算将来使用 Windows 身份验证,并相信 Kestrel 不会支持它(基于HTTP.sys 功能 https://learn.microsoft.com/en-us/aspnet/core/fundamentals/servers/httpsys).

  • 主机应作为 Windows 服务运行
    最终,Web API 应由 Windows Installer 安装并作为服务运行。
    目前,我只是想让 API 独立构建/正确工作,但也希望了解项目选择如何影响发布/部署的任何见解。

首选解决方案

虽然默认情况下,新的 ASP.NET Core 2 Web 应用程序是输出控制台应用程序的单个项目,但我更愿意将解决方案拆分为 2 个主要项目:

  • “服务器” - ASP.NET Core 2 (.NET Framework)类库包含Web API、控制器和Startup类的业务逻辑
  • “Host” - 引用“Server”并负责托管 Web API 的控制台应用程序

这种安排对我来说似乎很合适,因为任何单元/集成测试项目都可以引用“服务器”类库,而不是可执行文件(根据在 C# 项目中引用 exe 文件是一种不好的做法吗 https://stackoverflow.com/questions/22835635/is-it-a-bad-practice-to-reference-an-exe-file-in-c-sharp-project/22836012#22836012).

此外,我相信这是合理的,因为我可以在项目属性中将输出类型更改为“类库”。

我假设由于我的目标是 .Net Framework,只要我安装与“服务器”项目相同的 NuGet 包,“主机”项目就没有理由不能成为 Windows 经典桌面控制台应用程序。

是否存在任何隐藏的问题(可能与发布/部署相关)使得这种安排成为一个坏主意? 将托管项目设为 Web 应用程序(仍会引用服务器项目)是否有任何优势?

Attempt

以下是我用来尝试实现我喜欢的项目组织的步骤。虽然它有效,但我在构建过程中收到了生成的警告 - 见下文。

Server

  • 添加新项目“服务器”

    • 选择 Visual C#、Web、ASP.NET Core Web 应用程序

      在以下对话框中,目标为 .NET Framework、ASP.NET Core 2.0,然后选择 Web API

  • 将项目属性中的输出类型更改为“类库”
  • 删除程序.cs

Host

  • Add New Project "Host"
    • 选择 Visual C#、Windows 经典桌面、控制台应用程序 (.NET Framework)
  • 将 Program.cs 的内容替换为:

    using Microsoft.AspNetCore.Hosting;
    using Microsoft.Extensions.Logging;
    using Server;
    
    namespace Host
    {
      internal class Program
      {
        private static void Main(string[] args)
        {
          BuildWebHost(args).Run();
        }
    
        private static IWebHost BuildWebHost(string[] args) =>
          new WebHostBuilder()
            .UseStartup<Startup>()
            .UseHttpSys(options =>
            {
              options.UrlPrefixes.Add("http://localhost:8080/");
            })
            .ConfigureLogging((hostingContext, logging) =>
            {
              logging.AddConsole();
              logging.AddDebug();
            })
            .Build();
      }
    }
    
  • 添加对服务器项目的引用

  • Install these NuGet packages
    • Microsoft.AspNetCore (2.0.1)
    • Microsoft.AspNetCore.Mvc (2.0.1)
    • Microsoft.AspNetCore.Server.HttpSys (2.0.2)
  • 设置为启动项目

问题:构建生成警告

该解决方案在调试中运行,并正确响应http://localhost:8080/api/values and http://localhost:8080/api/values/1, but构建解决方案后会显示以下警告:

Warning     The referenced component 'System.Security.Cryptography.Encoding' could not be found.    Host            
Warning     The referenced component 'System.Xml.XPath' could not be found. Host            
Warning     The referenced component 'System.IO.FileSystem.Primitives' could not be found.  Host            
Warning     The referenced component 'System.IO.FileSystem' could not be found. Host            
Warning     The referenced component 'System.Diagnostics.StackTrace' could not be found.    Host            
Warning     The referenced component 'System.Xml.XmlDocument' could not be found.   Host            
Warning     The referenced component 'System.Security.Cryptography.X509Certificates' could not be found.    Host            
Warning     The referenced component 'System.Diagnostics.FileVersionInfo' could not be found.   Host            
Warning     The referenced component 'System.Security.Cryptography.Algorithms' could not be found.  Host            
Warning     The referenced component 'System.Xml.ReaderWriter' could not be found.  Host            
Warning     The referenced component 'System.Security.Cryptography.Primitives' could not be found.  Host            
Warning     The referenced component 'System.ValueTuple' could not be found.    Host            
Warning     The referenced component 'System.Xml.XPath.XDocument' could not be found.   Host            
Warning     The referenced component 'System.IO.Compression' could not be found.    Host            
Warning     The referenced component 'System.AppContext' could not be found.    Host            
Warning     The referenced component 'System.Threading.Thread' could not be found.  Host            
Warning     The referenced component 'System.Console' could not be found.   Host            

如果这是一个合理的项目安排,为什么我会收到这些警告?


我们正在做类似的事情。我们的宿主是一个 .NET Framework 4.7.1 项目:

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

  <PropertyGroup>
    <TargetFramework>net471</TargetFramework>
    <IsPackable>true</IsPackable>
    <PlatformTarget>x86</PlatformTarget>
    <OutputType>Exe</OutputType>
  </PropertyGroup>

  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
    <Prefer32Bit>false</Prefer32Bit>
  </PropertyGroup>

  <ItemGroup>
    <Folder Include="wwwroot\" />
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNet.WebApi.Core" Version="5.2.6" />
    <PackageReference Include="Microsoft.AspNetCore" Version="2.1.0" />
    <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.1.0" />
    <PackageReference Include="Microsoft.AspNetCore.Server.IISIntegration" Version="2.1.0" />
    <PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.1.0" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.1.0" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.1.0" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="2.1.0" />
    <PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="2.1.0" />
    <PackageReference Include="Microsoft.VisualStudio.Web.BrowserLink" Version="2.1.0" />
    <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.1.0" />
  </ItemGroup>

  <ItemGroup>
    <DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0" />
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\Business.csproj" />
    <ProjectReference Include="..\Apis.Shared.csproj" />
    <ProjectReference Include="..\Apis.Contracts.csproj" />
  </ItemGroup>

</Project>

而我们的库项目是NetStandard2.0:

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

  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
  </PropertyGroup>

  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
    <PlatformTarget>AnyCPU</PlatformTarget>
    <DebugType>full</DebugType>
    <DebugSymbols>true</DebugSymbols>
  </PropertyGroup>

</Project>

Program.cs 看起来像这样:

public class Program
{
    public static void Main(string[] args)
    {
        var host = new WebHostBuilder()
            .UseKestrel()
            .ConfigureServices(services => services.AddAutofac())
            .UseContentRoot(Directory.GetCurrentDirectory())
            .UseIISIntegration()
            .UseStartup<Startup>()
            .Build();

        host.Run();
    }

    public static IWebHost BuildWebHost(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>()
            .Build();
}

Startup.cs 看起来像这样:

public class Startup
{
    public Startup(IHostingEnvironment hostingEnvironment)
    {
        Settings = new AppSettings(hostingEnvironment);
    }

    public AppSettings Settings { get; private set; }

    public IServiceProvider ConfigureServices(IServiceCollection services)
    {
        services.AddMvc(); 
        services.AddOptions();      
        // any other services registrations...    

        var builder = new ContainerBuilder();           
        // all autofac registrations...
        builder.Populate(services);

        return new AutofacServiceProvider(builder.Build(););
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseMvc();
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将 ASP.Net Core 2 (.NET Framework) Web Api 拆分为类库和托管项目是否可能/明智? 的相关文章

  • 在哪里可以找到列出 SSE 内在函数操作的官方参考资料?

    是否有官方参考列出了 GCC 的 SSE 内部函数的操作 即 头文件中的函数 除了 Intel 的 vol 2 PDF 手册外 还有一个在线内在指南 https www intel com content www us en docs in
  • 不支持将数据直接绑定到存储查询(DbSet、DbQuery、DbSqlQuery)

    正在编码视觉工作室2012并使用实体模型作为我的数据层 但是 当页面尝试加载时 上面提到的标题 我使用 Linq 语句的下拉控件往往会引发未处理的异常 下面是我的代码 using AdventureWorksEntities dw new
  • ASP.NET MVC:这个业务逻辑应该放在哪里?

    我正在开发我的第一个真正的 MVC 应用程序 并尝试遵循一般的 OOP 最佳实践 我正在将控制器中的一些简单业务逻辑重构到我的域模型中 我最近一直在阅读一些内容 很明显我应该将逻辑放在域模型实体类中的某个位置 以避免出现 贫血域模型 反模式
  • 查找c中结构元素的偏移量

    struct a struct b int i float j x struct c int k float l y z 谁能解释一下如何找到偏移量int k这样我们就可以找到地址int i Use offsetof 找到从开始处的偏移量z
  • Asp.NET WebApi 中类似文件名称的路由

    是否可以在 ASP NET Web API 路由配置中添加一条路由 以允许处理看起来有点像文件名的 URL 我尝试添加以下条目WebApiConfig Register 但这不起作用 使用 URIapi foo 0de7ebfa 3a55
  • 嵌套接口:将 IDictionary> 转换为 IDictionary>?

    我认为投射一个相当简单IDictionary
  • 类模板参数推导 - clang 和 gcc 不同

    下面的代码使用 gcc 编译 但不使用 clang 编译 https godbolt org z ttqGuL template
  • BitTorrent 追踪器宣布问题

    我花了一点业余时间编写 BitTorrent 客户端 主要是出于好奇 但部分是出于提高我的 C 技能的愿望 我一直在使用理论维基 http wiki theory org BitTorrentSpecification作为我的向导 我已经建
  • Clang 3.1 + libc++ 编译错误

    我已经构建并安装了 在前缀下 alt LLVM Clang trunk 2012 年 4 月 23 日 在 Ubuntu 12 04 上成功使用 GCC 4 6 然后使用此 Clang 构建的 libc 当我想使用它时我必须同时提供 lc
  • 将 VSIX 功能添加到 C# 类库

    我有一个现有的单文件生成器 位于 C 类库中 如何将 VSIX 项目级功能添加到此项目 最终目标是编译我的类库项目并获得 VSIX 我实际上是在回答我自己的问题 这与Visual Studio 2017 中的单文件生成器更改 https s
  • 在 ASP.NET 5 中使用 DI 调用构造函数时解决依赖关系

    Web 上似乎充斥着如何在 ASP NET 5 中使用 DI 的示例 但没有一个示例显示如何调用构造函数并解决依赖关系 以下只是众多案例之一 http social technet microsoft com wiki contents a
  • 重载<<的返回值

    include
  • 显示UnityWebRequest的进度

    我正在尝试使用下载 assetbundle统一网络请求 https docs unity3d com ScriptReference Networking UnityWebRequest GetAssetBundle html并显示进度 根
  • IEnumerable 与 IReadOnlyList

    选择有什么区别IEnumerable
  • 如何序列化/反序列化自定义数据集

    我有一个 winforms 应用程序 它使用强类型的自定义数据集来保存数据进行处理 它由数据库中的数据填充 我有一个用户控件 它接受任何自定义数据集并在数据网格中显示内容 这用于测试和调试 为了使控件可重用 我将自定义数据集视为普通的 Sy
  • 如何将带有 IP 地址的连接字符串放入 web.config 文件中?

    我们当前在 web config 文件中使用以下连接字符串 add name DBConnectionString connectionString Data Source ourServer Initial Catalog ourDB P
  • 如何在Xamarin中删除ViewTreeObserver?

    假设我需要获取并设置视图的高度 在 Android 中 众所周知 只有在绘制视图之后才能获取视图高度 如果您使用 Java 有很多答案 最著名的方法之一如下 取自这个答案 https stackoverflow com a 24035591
  • 哪种 C 数据类型可以表示 40 位二进制数?

    我需要表示一个40位的二进制数 应该使用哪种 C 数据类型来处理这个问题 如果您使用的是 C99 或 C11 兼容编译器 则使用int least64 t以获得最大的兼容性 或者 如果您想要无符号类型 uint least64 t 这些都定
  • 如何在文本框中插入图像

    有没有办法在文本框中插入图像 我正在开发一个聊天应用程序 我想用图标图像更改值 等 但我找不到如何在文本框中插入图像 Thanks 如果您使用 RichTextBox 进行聊天 请查看Paste http msdn microsoft co
  • 对来自流读取器的过滤数据执行小计

    编辑问题未得到解答 我有一个基于 1 个标准的过滤输出 前 3 个数字是 110 210 或 310 给出 3 个不同的组 从流阅读器控制台 问题已编辑 因为第一个答案是我给出的具体示例的字面解决方案 我使用的实际字符串长度为 450 个

随机推荐