首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将属于动态加载的dll的类强制转换为属于另一个dll的抽象类

将属于动态加载的dll的类强制转换为属于另一个dll的抽象类
EN

Stack Overflow用户
提问于 2019-08-25 20:32:23
回答 1查看 83关注 0票数 0

我在从外部程序集中转换带有抽象类的ViewModel类时遇到了问题。

我有两个dll和一个可执行文件:

动态链接库Cockpit.RUN.Common.dll中的一个抽象类,这个动态链接库被引用:在动态链接库Cockpit.RUN.ViewModels的另一个工程和可执行文件Cockpit.RUN.Test所在的工程中,但在可执行文件所在的工程中不引用Cocpit.RUN.ViewModels,因为它是动态加载的

abstrac类:(dll)

代码语言:javascript
复制
using Caliburn.Micro;

namespace Cockpit.RUN.Common
{
    public abstract class PluginModel : PropertyChangedBase
    {
        public abstract double Width { get; set; }
        public abstract double Height { get; set; }
        public abstract double Left { get; set; }
        public abstract double Top { get; set; }

        private double zoomfactorfrompluginmodel;
        public double ZoomFactorFromPluginModel
        {
            get => zoomfactorfrompluginmodel;
            set
            {
                zoomfactorfrompluginmodel = value;
                NotifyOfPropertyChange(() => ZoomFactorFromPluginModel);
            }
        }
        public string NameUC;
    }
}

第二个动态链接库包含视图模型,我在这个动态链接库中有很多不同的插件: Push_ViewModel Cockpit.RUN.ViewModels.dll Switch_ViewModel...

例如,我使用Push_ViewModel的抽象类派生每个类:

代码语言:javascript
复制
using Cockpit.RUN.Common;
using System.Windows;
using System.Windows.Input;

namespace Cockpit.RUN.ViewModels
{
    public class PushButton_ViewModel : PluginModel
    {

        public PushButton_ViewModel(params object[] settings)
        {
            NameUC = (string)settings[2];
            Layout = new LayoutPropertyViewModel();
        }

        public override double Left
        {
            get => Layout.UCLeft;
            set => Layout.UCLeft = value;
        }
        public override double Top
        {
            get => Layout.UCTop;
            set => Layout.UCTop = value;
        }
        public override double Width
        {
            get => Layout.Width;
            set => Layout.Width = value;
        }
        public override double Height
        {
            get => Layout.Height;
            set => Layout.Height = value;
        }                         
    }
}

还有一件事,这个插件dll是在引导过程中动态加载的

代码语言:javascript
复制
    protected override IEnumerable<Assembly> SelectAssemblies()   
    {                                                                                                                                  
        var assemblies = new List<Assembly>();
        assemblies.AddRange(base.SelectAssemblies());
        assemblies.Add(Assembly.LoadFile(@"J:\ProjetC#\Cockpit-master\Cockpit.RUN.Test\bin\Debug\Cockpit.RUN.ViewModels.dll")); 
        assemblies.Add(Assembly.LoadFile(@"J:\ProjetC#\Cockpit-master\Cockpit.RUN.Test\bin\Debug\Cockpit.RUN.Views.dll")); 
        return assemblies;   
    }  

所以问题是,当我想用抽象基PulginModel强制转换每个ViewModels时,我的结果是空的:

代码语言:javascript
复制
        using Cockpit.RUN.Common;
                    :
                    :
        public BindableCollection<PluginModel> MyCockpitPlugins { get; set; }

                    :
                    :

        model = "Cockpit.RUN.ViewModels.PushButton_ViewModel, Cockpit.RUN.ViewModels";
        var typeClass = Type.GetType(model); // its ok 
        var viewmodel = resolutionRoot.TryGet(typeClass, param); // Its ok i have an instance of PushButton_ViewModel

        var v = viewmodel as PluginModel; //-> not ok its null
        var w = (PluginModel)viewmodel; //-> not ok its error

        // So i cant display my  list of views associated 
        MyCockpitPlugins.Add(v);

我是不是做错了什么?

转换前在中断调试时加载的程序集:

以及typeof和GetType的结果:

代码语言:javascript
复制
typeof(PluginModel) gives {Name = "PluginModel" FullName = "Cockpit.RUN.Common.PluginModel"}

viewmodel.GetType().BaseType gives {Name = "PluginModel" FullName = "Cockpit.RUN.ViewModels.PluginModel"}
EN

回答 1

Stack Overflow用户

发布于 2019-08-25 22:50:02

接口(dll):

代码语言:javascript
复制
public interface IPlugin
{
    ICallbacks Callbacks { get; set; }

    string NameUC { get; set; }

    double Width { get; set; }
    double Height { get; set; }
    double Left { get; set; }
    double Top { get; set; }

    double ZoomFactorFromPluginModel { get; set; }
}
public interface ICallbacks
{
    void SomeCallback();
}

您的实现:

代码语言:javascript
复制
public class PushButton_ViewModel : PluginModel, IPlugin
{
    // How was this going to work? Who makes the instance?
    //public PushButton_ViewModel(params object[] settings)
    //{
    //    NameUC = (string)settings[2];
    //    Layout = new LayoutPropertyViewModel();
    //}

    public ICallbacks Callbacks { get; set; }

    public override double Left
    {
        get => Layout.UCLeft;
        set => Layout.UCLeft = value;
    }
    public override double Top
    {
        get => Layout.UCTop;
        set => Layout.UCTop = value;
    }
    public override double Width
    {
        get => Layout.Width;
        set => Layout.Width = value;
    }
    public override double Height
    {
        get => Layout.Height;
        set => Layout.Height = value;
    }                         
}

然后初始化它

代码语言:javascript
复制
 Type t = Type.GetType("PushButton_ViewModel");
 object obj = FormatterServices.GetUninitializedObject(t);
 IPlugin instance = obj as IPlugin;
 instance.NameUC = "the name";
 instance.Callbacks = new CallbacksModel();
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57646030

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档