简体   繁体   English

自托管进程中 Web API 带点网核心

[英]Self-hosted In Process Web API with Dot net core

I am trying to investigate the plausibility of moving to dot net core now 3.0 has been released.我正在尝试调查迁移到 dot net core 的合理性,现在 3.0 已经发布。 One of our key components allows our (private) nugets to create their own WebAPI, providing events and methods to the consumer.我们的关键组件之一允许我们的(私有)nugets 创建自己的 WebAPI,为消费者提供事件和方法。 This supports functionality like remote service control, or remote service configuration, allowing the api to provide remote configuration setting/retrieval etc.这支持远程服务控制或远程服务配置等功能,允许 api 提供远程配置设置/检索等。

This functionality is key to how our micro-service architecture currently works.此功能是我们的微服务架构当前如何工作的关键。

I am trying to replicate this with dotnet core, however, I am struggling to find a direct equivalent tutorial/scenario.我正在尝试使用 dotnet core 复制它,但是,我正在努力寻找直接等效的教程/场景。 We essentially followed the process detailed here:我们基本上遵循了这里详述的过程:

https://docs.microsoft.com/en-us/aspnet/web-api/overview/hosting-aspnet-web-api/use-owin-to-self-host-web-api https://docs.microsoft.com/en-us/aspnet/web-api/overview/hosting-aspnet-web-api/use-owin-to-self-host-web-api

However, after checking the compatibility of the nuget packages (and everything looking OK..), I now just get null reference exceptions when calling WebApp.Start<Startup>(baseaddress);但是,在检查了 nuget 包的兼容性(并且一切看起来都不错..)之后,我现在在调用WebApp.Start<Startup>(baseaddress);

The null reference exception is apparently called by incompatibility of the nuget packages with .net core see here: null 参考异常显然是由 nuget 包与 .net 内核不兼容调用的,请参见此处:

NullReferenceException experienced with Owin on Startup.Net Core 2.0 - Settings? 在 Startup.Net Core 2.0 上使用 Owin 遇到 NullReferenceException - 设置?

The solution provided in the link is one way, but it uses a third-party application - NancyFx.链接中提供的解决方案是一种方式,但它使用了第三方应用程序 - NancyFx。 Is there any way to implement the same functionality with dotnet core in its current form?有没有办法以当前形式实现与 dotnet core 相同的功能? There was ample documentation for self-host before, but unfortunately given aspnet core runs in its own process, it is decidedly difficult to find a solution!以前有大量关于自托管的文档,但不幸的是,由于 aspnet 核心在自己的进程中运行,因此很难找到解决方案!

Can anyone point me in the right direction here?谁能在这里指出我正确的方向?

The code is shown below代码如下所示

//the external library would contain all this code. I.e. this could present the configuration endpoints as mentioned above.

public class Startup
{
    // This code configures Web API. The Startup class is specified as a type
    // parameter in the WebApp.Start method.
    public void Configuration(IAppBuilder appBuilder)
    {
        // Configure Web API for self-host. 
        HttpConfiguration config = new HttpConfiguration();
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
        appBuilder.UseWebApi(config);
    }
}

public class WebAPI:IDisposable
{
    private IDisposable _webApp;
    public WebAPI()
    {
        string baseAddress = "http://localhost:8800/";
        _webApp = WebApp.Start<Startup>(baseAddress); // << This line throws null reference exception 
    }
    #region IDisposable Support
    private bool disposedValue = false; // To detect redundant calls

    protected virtual void Dispose(bool disposing)
    {
        if (!disposedValue)
        {
            if (disposing)
            {
                _webApp.Dispose();
                _webApp = null;
            }                
            disposedValue = true;
        }
    }

    public void Dispose()
    {
        Dispose(true);
    }
    #endregion
}

public class ValuesController:ApiController
{
    // GET api/values 
    public IEnumerable<string> Get()
    {
        return new string[] { "value1", "value2" };
    }

    // GET api/values/5 
    public string Get(int id)
    {
        return "value";
    }
}

The main app, the host/consumer of the library above.主应用程序,上述库的主机/消费者。

class Program
{
    static void Main()
    {
        var webapi = new WebApiTest.WebAPI();
        Console.WriteLine("Running...");
        Console.ReadLine();
        webapi.Dispose();
    }
}

I did eventually figure this out.. basically, I looked at the project stub that was created with the new dotnet core webapi project, and then rewrote the startup class so that it was less fixed.我最终弄明白了.. 基本上,我查看了使用新的 dotnet core webapi 项目创建的项目存根,然后重写了启动 class 以便它不那么固定。 This meant I could use my own dependency injection container from the main application and everything could kinda hook up as expected.这意味着我可以在主应用程序中使用我自己的依赖注入容器,并且一切都可以按预期连接。 I must add this isnt battle tested, or really tested much at all, the project took a backseat, but the principle works and just needs refining/customising to suit.我必须补充一点,这没有经过实战测试,或者根本没有经过真正的测试,该项目退居二线,但原理有效,只需要改进/定制以适应。

The only piece of code of interest is the new "Api" class, which in my case starts/stops the API on demand: (the configurations can probably be removed, but was trying to customise the API as much as possible)唯一感兴趣的代码是新的“Api”class,在我的情况下,它可以按需启动/停止 API:(可能可以删除配置,但试图尽可能多地自定义 ZDB974238714CA8DE634A7CE1D083A1)

public class Api:IDisposable
    {
        private readonly IHost _host;
        private readonly IConfigurationManager _configManager;

        public Api(DryIoc.IContainer container, IConfigurationManager configManager)
        {
            _host = CreateBuilder(Array.Empty<string>(), container).Build();
            _configManager = configManager;
            _configManager.Build($"{nameof(Api)}_IOSource");
        }

        public async void Start()
        {
            await _host.StartAsync();
        }

        public async void Stop()
        {
            await _host.StopAsync();
        }

        private IHostBuilder CreateBuilder(string[] args, DryIoc.IContainer container = null)
        {
            return new HostBuilder()
                //CreateDefaultBuilder, taken from source, to allow custom useserviceproviderfactory
                .UseContentRoot(Directory.GetCurrentDirectory())
                .ConfigureHostConfiguration(config =>
                {
                    config.AddEnvironmentVariables(prefix: "DOTNET_");
                    if (args != null)
                    {
                        config.AddCommandLine(args);
                    }
                })
                .ConfigureAppConfiguration((hostingContext, config) =>
                {
                    var env = hostingContext.HostingEnvironment;

                    config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                        .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);

                    if (env.IsDevelopment() && !string.IsNullOrEmpty(env.ApplicationName))
                    {
                        var appAssembly = Assembly.Load(new AssemblyName(env.ApplicationName));
                        if (appAssembly != null)
                        {
                            config.AddUserSecrets(appAssembly, optional: true);
                        }
                    }

                    config.AddEnvironmentVariables();

                    if (args != null)
                    {
                        config.AddCommandLine(args);
                    }
                })
                .UseServiceProviderFactory(new DryIocServiceProviderFactory(container))
                .ConfigureLogging((hostingContext, logging) =>
                {
                    var isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);

                    // IMPORTANT: This needs to be added *before* configuration is loaded, this lets
                    // the defaults be overridden by the configuration.
                    if (isWindows)
                    {
                        // Default the EventLogLoggerProvider to warning or above
                        logging.AddFilter<EventLogLoggerProvider>(level => level >= LogLevel.Warning);
                    }

                    logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
                    logging.AddConsole();
                    logging.AddDebug();
                    logging.AddEventSourceLogger();

                    if (isWindows)
                    {
                        // Add the EventLogLoggerProvider on windows machines
                        logging.AddEventLog();
                    }
                })
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup<Startup>();
                    webBuilder.UseUrls("http://localhost:12000/");
                });
        }

        //This is the original code thats generated by dotnet for new webapi projects
        //private IHostBuilder CreateHostBuilder(string[] args) =>
        //    //new WebHostBuilder().Build();
        //    Host.CreateDefaultBuilder(args)
        //        .ConfigureWebHostDefaults(webBuilder =>
        //        {
        //            webBuilder.UseStartup<Startup>();
        //            webBuilder.UseUrls("http://localhost:12000/");
        //        });

        public void Dispose()
        {
            _host?.Dispose();
        }
    }

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

相关问题 .NET 6 中的自托管 Web API - Self-Hosted Web API in .NET 6 在ASP.NET自托管Web API上配置SSL - Configuring SSL on ASP.NET Self-Hosted Web API 在自托管Web Api中检测上下文 - Detect context in Self-hosted Web Api ASP.NET Core 3.1 Web API: can it be self-hosted as Windows service with https and use some certificate like IIS? - ASP.NET Core 3.1 Web API : can it be self-hosted as Windows service with https and use some certificate like IIS? 更新配置并根据HTTP请求重新启动自托管的ASP.NET Web API 2 - Update configuration and restart self-hosted ASP.NET Web API 2 on HTTP request 自托管的OWIN .NET 4.5 Web API 2不适用于Windows身份验证和https - Self-hosted OWIN .NET 4.5 Web API 2 does not work with Windows authentication and https 自托管 Net Core 3 应用程序不采取端口设置 - Self-hosted Net Core 3 application does not take port settings 自托管 .NET 核心控制台应用程序中的 Startup.cs - Startup.cs in a self-hosted .NET Core Console Application 依赖注入无法与Owin自托管Web Api 2和Autofac一起使用 - Dependency injection not working with Owin self-hosted Web Api 2 and Autofac 在自托管 OWIN Web API 中,如何在关机时运行代码? - In self-hosted OWIN Web API, how to run code at shutdown?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM