如何处理特定于目标的方法,例如.NET Standard 库项目中的 WinForms 或 Blazor?

问题描述 投票:0回答:1

我想使用 .NET Standard 2.0 库项目在 .NET Framework 4.7.2 WinForms 和 .NET 6.0 Blazor 应用程序之间共享代码。我应该使用依赖注入来实现依赖于目标应用程序的库中的方法吗?例如。在使用 WinForms 或 Blazor 显示用户消息时?

如果依赖注入是要走的路,你能提供一个关于如何实现上面例子的大纲吗?没有依赖注入容器能做到吗?

c# winforms dependency-injection blazor .net-standard-2.0
1个回答
0
投票

我经常用我的应用程序做这种事情,这些应用程序在 WinForms 和 Xamarin 之类的东西之间是跨平台的。我发现执行此操作的一种更简单的方法是制作可移植库类

abstract
,强制客户端继承提供平台相关代码的类。让您的客户使用
RuntimePlatform
枚举来标识自己也很方便。或者,
virtual
方法会起作用,但会产生“无声失败”,除非它们抛出
NotImplementedException
在这一点上为什么不
abstract
它。

using System.Diagnostics;
using System.Threading.Tasks;

namespace net6_portable_library
{
    public enum RuntimePlatform
    {
        WinOS,
        Android,
        iOS,
        Web,
        MAUI,
    }
    public abstract class BusinessLogic
    {
        public BusinessLogic(RuntimePlatform platform) => RuntimePlatform = platform;
        protected abstract Task<bool> DisplayAlert(string title, string message, string accept, string cancel);
        public async Task<bool> TestPopup()
        {
            bool result = await DisplayAlert(
                title: "Demo", 
                message: $"Is {RuntimePlatform} popup visible?", accept: "Yes", cancel: "No");

            Debug.WriteLine($"Dialog returned {result}");
            return result;
        }
        public RuntimePlatform RuntimePlatform { get; }
    }
}

我成功的另一个选择是在特定于平台的客户端可以填充的 PCL 库中拥有

interface
delegate
成员。


WinForms 客户端

using System;
using System.Threading.Tasks;
using System.Windows.Forms;
using net6_portable_library;

public partial class MainForm : Form
{
    public MainForm()
    {
        InitializeComponent();
        buttonTestLibrary.Click += onClickTestLibrary;
    }
    private void onClickTestLibrary(object sender, EventArgs e)
    {
        _ = _lib.TestPopup();
    }
    // Consume library
    BusinessLogic _lib = new PlatformBusinessLogic(RuntimePlatform.WinOS);
}
class PlatformBusinessLogic : BusinessLogic
{
    public PlatformBusinessLogic(RuntimePlatform platform) : base(platform) { }

    protected override async Task<bool> DisplayAlert(string title, string message, string accept, string cancel)
    {
        var buttons = $"{accept}.{cancel}".ToUpper();
        switch (buttons) 
        {
            case "YES.NO":
                bool result = false;
                await Task.Run(() =>
                {
                    result = DialogResult.Yes.Equals
                    (
                        MessageBox.Show(text: message, caption: title, MessageBoxButtons.YesNo)
                    );
                });
                return result;
            default:
                throw new NotImplementedException($"TODO: Handler for {buttons}.");
        }
    }
}

安卓客户端

namespace maui_client_of_portable_library
{
    public partial class MainPage : ContentPage
    {
        int count = 0;

        public MainPage()
        {
            InitializeComponent();
        }
        // Consume library
        BusinessLogic _lib = new PlatformBusinessLogic(RuntimePlatform.MAUI);

        private void onClickTestLibrary(object sender, EventArgs e)
        {
            _ = _lib.TestPopup();
        }
    }
    class PlatformBusinessLogic : BusinessLogic
    {
        public PlatformBusinessLogic(RuntimePlatform platform) : base(platform) { }

        protected override async Task<bool> DisplayAlert(string title, string message, string accept, string cancel)
        {
            return await Shell.Current.CurrentPage.DisplayAlert(title, message, accept, cancel);
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.