首页 文章

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

提问于
浏览
7

我正在尝试使用Visual Studio 2017(v15.4.5)将现有的WCF Web API(以.NET Framework 4.6.1为目标)移植到ASP.Net Core 2,并且无法确定组织项目的良好/通用/支持方式,以及他们应该是什么类型的项目 .

例如:

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

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

我有一种潜在的怀疑,即我缺少一些基本的东西,这意味着一种方法应该优于其他方法,或者甚至是强制性的,但是发现很难从_770322中发现这种方法 .

具体要求

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

  • Host using HTTP.sys
    我打算将来使用Windows身份验证,并相信Kestrel不会支持(基于HTTP.sys features) .

  • Host should run as a Windows Service
    最终,Web API应由Windows Installer安装并作为服务运行 .
    目前,我只是想让API独立构建/工作,但也希望能够深入了解项目选择如何影响发布/部署 .

首选解决方案

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

  • "Server" - 包含Web API,控制器和Startup类的业务逻辑的ASP.NET Core 2(.NET Framework) Class Library

  • "Host" - 引用"Server"的控制台应用程序,负责托管Web API

这种安排对我来说似乎很合适,因为任何单元/集成测试项目都可以引用"Server"类库,而不是可执行文件(根据Is it a bad practice to reference an exe file in C# project中的建议) .

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

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

是否有任何隐藏的问题,可能与发布/部署有关,这使得这种安排成为一个坏主意?使Hosting项目成为Web应用程序(仍会引用Server项目)会有什么好处吗?

尝试

以下是我用来尝试实现我首选项目组织的步骤 . 虽然它有效,但我会在构建过程中收到警告 - 见下文 .

服务器

  • 添加新项目“服务器”

  • 选择Visual C#,Web,ASP.NET核心Web应用程序

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

  • 将项目属性中的输出类型更改为"Class Library"

  • 删除Program.cs

主持人

  • 添加新项目"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();
  }
}
  • 添加对Server项目的引用

  • 安装这些NuGet包

  • Microsoft.AspNetCore (2.0.1)

  • Microsoft.AspNetCore.Mvc (2.0.1)

  • Microsoft.AspNetCore.Server.HttpSys (2.0.2)

  • 设置为启动项目

问题:构建生成警告

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

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

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

1 回答

  • 0

    我们正在做类似的事情 . 我们的主机是.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();
        }
    }
    

相关问题