【问题标题】:Using Prism for building a Plugin (.dll)使用 Prism 构建插件 (.dll)
【发布时间】:2021-10-23 10:15:04
【问题描述】:

我正在开发一个插件,用于我使用的软件。通过附加从我的代码生成的 .dll 将软件插件附加到软件。因此,该软件的文档要求您有一个特定的类(称为 CPlugin)作为插件的入口点。

我正在阅读的所有使用 Prism 的教程都是您将项目作为 WPF 应用程序启动的地方。这样,您的项目将拥有 App.xaml 和 App.cs 文件,您可以在其中开始实施 Prism 框架。编译代码(对于 WPF 应用程序)也会生成 .exe 而不是 .dll。

我设置插件的方式是从 C# 类开始我的项目。然后,我将创建我的 CPlugin 类并启动我的所有变量,然后显示我的 MainView,它创建了我的 ViewModel 并从那里获取它。没有 App.xaml 或 App.cs。我不确定如何在我的限制下使用 Prism。

这是我正在为其开发插件的软件:https://www.csiamerica.com/products/etabs 在安装目录中安装时;可以找到解释如何开发或启动插件的 API 帮助文件。以下是相关信息的示例:

在您的插件中,所有功能都必须在名为 cPlugin 的类中实现。

类 cPlugin 必须包含一个子例程 cPlugin.Main,它有两个 ETABSv1.cSapModel 类型的参考参数和 ETABSv1.cPluginCallback

还有

添加 .NET 插件 添加 .NET 插件的过程要简单得多。在“外部插件数据”表单中,用户只需浏览并选择插件 .NET DLL,然后单击“添加”按钮

以下是显示空窗口的插件的一些示例代码: 创建一个 C# 类库文件 (.NET Framework),将 API 作为我的参考之一。

CPlugin.cs:

using Combonito.Views;          // Access Views (open window)

using CSiAPIv1;                  //to Access ETABS/SAP2000 API
using System;
using static Globals;

namespace Combonito
{
    // cPlugin has to be implemented in ETABS Plugins, it has to contain two functions Main() and Info()
    public class cPlugin
{

    private MainView _MyForm;

    //Entry point of plugin - has to exist with this exact signature
    // must call Finish() when plugin is closed!
    public void Main(ref cSapModel _SapModel, ref cPluginCallback _ISapPlugin)
    {
        ParentPluginObject = this;
        SapModel = _SapModel;
        ISapPlugin = _ISapPlugin;

        try
        {
            _MyForm = new MainView();   //Create MainView
            _MyForm.ShowDialog();       // Display window
        }
        catch (Exception ex)
        {
            try
            {
                ISapPlugin.Finish(1);
                Console.WriteLine(ex);
            }
            catch (Exception ex1)
            {
                Console.WriteLine(ex1);
                throw;
            }
        }
    }

    // return value should be 0 if successful
    public int Info(ref string txt)
    {
        try
        {
            txt = "Plugin is written by Moustafa El-sawy (mk.elsawy@live.com)";
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);
            throw;
        }

        return 0;
    }

    //Deconstructor to clean up
    ~cPlugin()
    {
        Console.WriteLine(GC.GetGeneration(0));
    }
}

}

然后我有一个空窗口 MainView 和一个视图模型 MainWindowViewModel。

编辑:这是启动任何类似于我上面显示的插件的锅炉初始值,但有更多解释https://kinson.io/post/etabs-plugin-quickstart/

【问题讨论】:

  • 我很困惑。你在这里问问题吗?
  • 是的。我不知道如何将 Prism 用于上述用例,因为我不是在创建 C# WPF 应用程序,而是在创建 C# 类文件。
  • 在 Prism 中,您在 XAML 中定义一个区域。您使用 RegionManager 将该区域导航到已注册的视图。你这样做吗?您是否正在执行代码以将在 XAML 中定义的某个区域导航到已注册的视图?
  • 要附加一个dll,你需要知道dll的导入格式。检查 MEF 或 Unity 是否用于依赖注入
  • @Joe 在 Prism 中的第一步是设置您的 App.xaml 或 App.cs 以创建您的 shell。我没有那个,那我将如何使用 Prism?

标签: wpf prism


【解决方案1】:

你的起点应该是Bootstrapper

首先你需要安装:

  • Prism.Unity
  • Prism.Wpf

需要创建你的引导程序基于 https://github.com/PrismLibrary/Prism/blob/master/src/Wpf/Prism.Wpf/PrismBootstrapperBase.cs

覆盖虚拟方法以创建 Shell(这是包含区域的主视图

覆盖虚拟方法来配置您的容器。 最后注册你的视图和视图模型

P.S.:考虑为每个注册类型使用一个接口,例如IShellViewModel

using Prism;
using Prism.Ioc;
using Prism.Unity;
using System.Windows;

namespace PrismTest
{
    public class Bootstrapper : PrismBootstrapperBase
    {
        protected override IContainerExtension CreateContainerExtension()
        {
            return new UnityContainerExtension();
        }

        protected override DependencyObject CreateShell()
        {
            return Container.Resolve<Shell>();
        }

        protected override void RegisterTypes(IContainerRegistry containerRegistry)
        {
             containerRegistry.Register<IShellViewModel, ShellViewModel>();
        }
    }
}

从你的插件调用你的引导程序:

Bootstrapper bootstrapper = new Bootstrapper();
bootstrapper.Run();

您的视图(外壳)

<Window
    x:Class="PrismTest.Shell"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="clr-namespace:PrismTest"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    Title="Shell"
    Width="800"
    Height="450"
    mc:Ignorable="d">
    <Grid>
        <TextBox Text="{Binding MyText}" />
    </Grid>
</Window>

在 Shell.xaml.cs 中:使用您的视图模型。这个也可以自动注入

public partial class Shell : Window
{
    private readonly IUnityContainer _container;
    public Shell(IUnityContainer container)
    {
        InitializeComponent();

        _container = container;

        this.DataContext = _container.Resolve<IShellViewModel>();

    }
}

你的视图模型

public class ShellViewModel : BindableBase, IShellViewModel
{
    private string m_MyText = "Shell ViewModel Text";

    public string MyText
    {
        get { return m_MyText; }
        set { SetProperty(ref m_MyText, value); }
    }
}

你的界面:

internal interface IShellViewModel
{
   string MyText { get; set; }
}

结果视图;

【讨论】:

  • 感谢您的评论,但我可能有点初学者理解这一点。你能看看这个:kinson.io/post/etabs-plugin-quickstart。这显示了如何创建插件。我的插件必须从 CPlugin 类开始(我已经在我的原始帖子中写过)。您能否让我了解如何修改它以实现引导程序的正确方向?我当前的工作流程是 CPlugin --> 打开第一个窗口 --> 初始化视图模型。第一个窗口将打开链接到其他视图模型的其他窗口。
  • 创建自定义容器的步骤最后对App类进行了修改prismlibrary.com/docs/dependency-injection/…
  • @MElSawy 所以我已经编辑了详细的答案。
  • 在使用 Unity 的时候为什么要Register&lt;ShellViewModel, ShellViewModel&gt;()? Unity 会自动解析具体类型,所以这个语句只是令人困惑......尤其是。如果你知道你可以写Register&lt;ShellViewModel&gt;()
  • @Haukinger,实际上我已经提到过,他应该使用像 IShellViewModel 这样的接口。我把它打开了
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多