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

C# 将属于动态加载的dll的类强制转换为属于另一个dll的抽象类,c#,ninject,caliburn.micro,C#,Ninject,Caliburn.micro,我在从外部程序集中转换ViewModel类和抽象类时遇到问题 我有两个DLL和一个可执行文件: 将一个抽象类放入dll cackpoint.RUN.Common.dll,引用此dll: 在另一个项目中的dll caffick.RUN.ViewModels 在可执行caffick.RUN.Test项目中, 但是Cocpit.RUN.ViewModels在可执行文件的项目中没有被引用,因为它是动态加载的 abstrac类:(dll) 第二个dll,其中包含viewmodels.RUN.viewmod

我在从外部程序集中转换ViewModel类和抽象类时遇到问题

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

将一个抽象类放入dll cackpoint.RUN.Common.dll,引用此dll: 在另一个项目中的dll caffick.RUN.ViewModels 在可执行caffick.RUN.Test项目中, 但是Cocpit.RUN.ViewModels在可执行文件的项目中没有被引用,因为它是动态加载的

abstrac类:(dll)

第二个dll,其中包含viewmodels.RUN.viewmodels.dll 我在这个dll中有很多不同的插件: 按下视图模型,切换视图模型

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

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是在引导程序中动态加载的

    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;   
    }  
接口(dll):

您的实施:

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;
    }                         
}
然后初始化它

 Type t = Type.GetType("PushButton_ViewModel");
 object obj = FormatterServices.GetUninitializedObject(t);
 IPlugin instance = obj as IPlugin;
 instance.NameUC = "the name";
 instance.Callbacks = new CallbacksModel();

如何确保类
PluginModel
所在的程序集对于可执行文件以及“caffict.RUN.ViewModels.dll”引用的程序集是相同的?检查加载的程序集和版本。“caffict.RUN.ViewModels.dll”文件使用的
PluginModel
类可能与可执行文件中的
PluginModel
引用不相同。将
viewmodel.GetType().BaseType
typeof(PluginModel)进行比较
查看它们是否引用同一个类。@progman我只有一个PluginModel的类定义,这个dll在解决方案的其他项目中引用。我已经检查了加载的程序集我看不出问题…使用接口?@progman我已经编辑了问题并显示了TypeOf和GetType()的结果@Frenchy你能用“Make object ID”检查一下吗在调试会话中或通过其他方式返回的两个类型实际上是相同的
System.Type
对象,而不仅仅是不同的类型对象,它们随机引用名为“PluginModel”的类的两个不同类型实例?还要检查调试会话中有关这两种类型的其他调试信息,以验证它们是否在同一版本和生成时引用了来自同一程序集的同一类。请包含当您尝试使用
var w=(PluginModel)viewmodel强制转换对象时收到的完整错误消息/异常。感谢您的回答,但我无法直接将其应用于我的项目…我的实例是由resolutionRoot.TryGet()方法(Ninject)构建的。但我把这一点牢记在心…所以我的问题解决了,原因是系统繁忙…不知道为什么…但重新启动后,现在一切似乎都好了…更频繁地清理解决方案,这可能也有帮助。我不喜欢注入解决方案,我认为这就是为什么它们有接口,这是您在c#简介第2页(在“类”之后)学到的。不要误解我的意思,我喜欢这是可能的,但实际上在正常项目中使用它是过分的。此外,我认为您过度考虑了我的解决方案,实现接口是在现有代码之上的,以正确的方式进行,您不应该更改任何现有代码(构造函数除外;)
typeof(PluginModel) gives {Name = "PluginModel" FullName = "Cockpit.RUN.Common.PluginModel"}

viewmodel.GetType().BaseType gives {Name = "PluginModel" FullName = "Cockpit.RUN.ViewModels.PluginModel"}
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();
}
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;
    }                         
}
 Type t = Type.GetType("PushButton_ViewModel");
 object obj = FormatterServices.GetUninitializedObject(t);
 IPlugin instance = obj as IPlugin;
 instance.NameUC = "the name";
 instance.Callbacks = new CallbacksModel();