ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

asp.net core 宿主于windows程序

2022-02-20 21:36:25  阅读:154  来源: 互联网

标签:core asp string windows net public winform


工作需要,我想在一个windows程序中提供webAPI的来提供打印服务。于是想到将asp.net core做的webapi放在windows上。今天又冷又下雨,哪也不去了,就在家为公司的方案做一些技术调研吧。

asp.net core是可能跑在命令行下的。于是想能否直接转为一个windows程序呢?是可以的,项目的选项就有,只是不彻底。就是无法添加新的Form。于是点击项目文件,看其文本,修改为类似以下形式,就变成一个真正的winform项目。不过在2019会有错误,在这种项目下添加的Form,打开设计界面打开会报错。所以winform还在放在其他项目吧。

 

有博主将asp.net core项目以引用的方式添加到wpf的程序里,在wpf里直接调用。不过我使用winform项目引用添加asp.net core项目时,也会报上面所说的一样的错误。于是,我将asp.net core转为winform项目后,作为主项目使用。另建一个winform项目编译所有的Form,以引用的形式添加到主项目。

net5有注入,所以我就用net5开始了我的摸索。注入的知识可以看以下地址

https://www.cnblogs.com/artech/p/net-core-di-06.html

先定义两个交互的接口

namespace WebApi.Interface
{
    /// <summary>
    /// 宿主创建
    /// </summary>
    public interface IMyApiHost
    {
        Microsoft.Extensions.Hosting.IHost BuildHost(IFormUI formUI);
    }
    /// <summary>
    /// 主UI界面
    /// </summary>
    public interface IFormUI
    {
        string SayHello(string name);
        string[] GetCommandArgs();
    }
}
View Code

winform项目准备一个启动器给主项目使用

namespace WebApiTestOnWin.App
{
    /// <summary>
    /// 界面启动器。
    /// </summary>
    public class UIStarter
    {
        public IServiceProvider ApplicationService { get; private set; }
        public IServiceProvider ScopedService { get; private set; }
       
        public void StartConfig(IMyApiHost apiHost)
        {            
            var services = new ServiceCollection();            
            services.AddSingleton<MainForm>();            
            services.AddSingleton(apiHost);

            ApplicationService = services.BuildServiceProvider();
            ScopedService = ApplicationService.CreateScope().ServiceProvider;
        }

        public Form BuildMainForm()
        {
            var mainWindow = ScopedService.GetRequiredService<MainForm>();
            return mainWindow;
        }
    }
}

对于winform来说IMyApiHost是未知的。以下是MainForm的部分代码。原构造函数需要加上一个入参,以接收这个必要的IMyApiHost。

namespace WebApiTestOnWin.App
{
    public partial class MainForm : Form,IFormUI
    {
        IMyApiHost myHost;
        //public Form1()
        //{
        //    InitializeComponent();
        //}
        public MainForm(IMyApiHost api)
        {
            InitializeComponent();
            this.myHost = api;            
        }        

        private void button1_Click(object sender, EventArgs e)
        {
            myHost.BuildHost(this).RunAsync();//启动asp.net core
        }
        public string SayHello(string name)
        {
            if (this.InvokeRequired)
            {
                var result = this.BeginInvoke(new SayHandler(this.SayHello), new object[] { name });
                result.AsyncWaitHandle.WaitOne(-1);
                return (string)this.EndInvoke(result);
            }
            this.lblMsg.Text = name + " saying...";
            return $"hi! {name},it's form.";
        }
        public string[] GetCommandArgs()
        {
            return Environment.GetCommandLineArgs();
        }
//........
}
View Code

好了,winform项目准备好了。看看asp.net core如何使用这个UIStarter。

使用前,asp.net core需要准备IMyWebApiHost的实现。其实就是将asp.net core的启动包装起来,以备MainForm使用。

namespace WebApiSimpleSite
{
    public class MyWebApiHostBuilder : MarshalByRefObject, IMyApiHost
    {
        IFormUI myFormUI;
        IHost host;
        public Microsoft.Extensions.Hosting.IHost BuildHost(IFormUI formUI)
        {
            myFormUI = formUI;
            string[] args = formUI.GetCommandArgs();
            var builder = Host.CreateDefaultBuilder(args);           
            var host = builder.ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.ConfigureServices((svc)=>svc.AddSingleton(myFormUI) );
                    webBuilder.UseStartup<Startup>();
                });
            return host.Build();
        }
    }
}

好了,程序准备好了。在asp.net core(已手工转换为winform程序)中启动MainForm

namespace WebApiSimpleSite
{
    public class Program
    {
        public static void Main(string[] args)
        {
            //CreateHostBuilder(args).Build().Run(); //原启动asp.net core的命令行代码           
            UIStarter starter = new UIStarter();//引用winform后,使用其UIStarter
            starter.StartConfig(new MyWebApiHostBuilder());//将asp.net core的启动器传入,以完成其配置           
            Form formMain = starter.BuildMainForm();//创建主程序
            Application.Run(formMain);
        }
}

IFormUI是准备给Controller使用的。目的就是利用webapi控制winform。以下是Hello方法测试了这个过程

namespace WebApiSimpleSite.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class PrintController : ControllerBase
    {
        IFormUI myFormUI;
        public PrintController(IFormUI formUI)
        {
            myFormUI = formUI;
        }
        [HttpGet]
        public string Hello(string yourname)
        {
            return myFormUI.SayHello(yourname);
        }
    }
}

 

以下是程序运行效果。web程序已可控制了winform程序

 

标签:core,asp,string,windows,net,public,winform
来源: https://www.cnblogs.com/kevin-Y/p/15916609.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有