iT邦幫忙

0

NET6 WPF API 存取function問題

  • 分享至 

  • xImage

我WPF專案中還有開一個API 讓使用者可以call網址 直接觸發撥放的部分
用 Caliburn.Micro 框架
用POSTMAN測試 寫法1 回傳 415 寫法2 回傳 500
目前問題是 ApiController 吃不到DI的function
程式碼
bootstrapper.cs

public partial class Bootstrapper : BootstrapperBase
{
    private readonly SimpleContainer _container = new SimpleContainer();
    public Bootstrapper()
    {
        Initialize();
    }
    protected override void Configure()
    {
        _container.Singleton<MainViewModel>();
    }

    protected override void OnStartup(object sender, StartupEventArgs e)
    {
        DisplayRootViewForAsync<LoginViewModel>();
    }
}

MainViewModel.cs

public partial class MainViewModel : Conductor<Screen>
{
    //寫法2#
    ApiController api;
    //end2#
    public MainViewModel()
    {
        //init略
        //2#
        api = new ApiController(this);
        //end2#
    }
    
    public void PlayEmergency()
    {
        Play(true);
    }
    
    public void Play(bool IsEmergency = false)
    {
        //播放
    }
}

apiController.cs

using Microsoft.AspNetCore.Mvc;
[ApiController]
public class ApiController : ControllerBase
{
    //寫法1#
    [Route("api/Emergency")]
    [HttpGet]
    public void Emergency(MainViewModel _mv)
    {
        //目前問題是在這邊
        _mv.PlayEmergency();
    }
    //end1#
    
    //寫法2#
    MainViewModel mv;
    public ApiController(MainViewModel _mv)
    {
        mv = _mv;
    }
    public void Emergency()
    {
        try
        {
            mv.PlayEmergency();
        }
        catch (Exception ex)
        {
            console.WriteLine(ex.Message);
//輸出 System.InvalidOperationException: Unable to resolve service for type 'ViewModels.MainViewModel' while attempting to activate 'Controller.ApiController'.
        }
    }
    //end2#
}

apiServer.cs

using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
class ApiServer
{
    // Api Server 
    public void OpenServer()
    {
        var builder = WebApplication.CreateBuilder(new string[] { });
        builder.Services.AddControllers();
        var app = builder.Build();
        app.Urls.Add("http://0.0.0.0:8080"); // 手動設定port
        app.MapControllers();
        app.RunAsync();
    }
}
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 個回答

1
kanework
iT邦新手 5 級 ‧ 2023-04-10 16:19:01

根據您的程式碼,您正在使用 Caliburn.Micro 框架,並且正在嘗試在 API 控制器中使用 DI(依賴注入)來使用 MainViewModel 的功能。

在您的 Bootstrapper 類別的 Configure 方法中,您只是設置了 _container.Singleton(),但您沒有為 ApiController 創建一個實例。

您可以將以下代碼添加到 Configure 方法中,以註冊 ApiController 的實例:

_container.Singleton<ApiController>();

這將在應用程序啟動時創建 ApiController 的單一實例,並且該實例將使用 DI 來注入 MainViewModel。在您的 ApiController 中,您可以刪除 Emergency 方法的 _mv 參數,因為它將使用 DI 從 _container 中注入 MainViewModel 的實例。

修改後的 Bootstrapper 類別的 Configure 方法應如下所示:

protected override void Configure()
{
    _container.Singleton<MainViewModel>();
    _container.Singleton<ApiController>();
}

修改後的 ApiController 類別的 Emergency 方法應如下所示:

[Route("api/Emergency")]
[HttpGet]
public void Emergency()
{
    mv.PlayEmergency();
}

現在,您可以使用 POSTMAN 測試 API,並且您應該可以成功調用 PlayEmergency 方法。

我要發表回答

立即登入回答