C# 从动态加载的控制器中无法访问静态

C# 从动态加载的控制器中无法访问静态,c#,.net-core,asp.net-core-mvc,C#,.net Core,Asp.net Core Mvc,我这里有一个插件系统,它检查程序集的基类实现。一个基类应该提供一个API,但当我点击控制器时,静态变量会忘记它们的值,并且总是返回它们的默认值 插件系统创建如下模块实例: var assembly = Assembly.LoadFile(@"absolute\path\to\TestModule.dll"); var types = assembly.GetTypes().Where(t => t.IsSubclassOf(typeof(ModuleBase))); ModuleBase

我这里有一个插件系统,它检查程序集的基类实现。一个基类应该提供一个API,但当我点击控制器时,静态变量会忘记它们的值,并且总是返回它们的默认值

插件系统创建如下模块实例:

var assembly = Assembly.LoadFile(@"absolute\path\to\TestModule.dll");
var types = assembly.GetTypes().Where(t => t.IsSubclassOf(typeof(ModuleBase)));

ModuleBase instance = (ModuleBase)Activator.CreateInstance(types.FirstOrDefault());
instance.Execute();
public class Startup
{
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        app.UseMvc();
    }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();
    }
}
到目前为止效果不错。插件基本类型尽可能少:

    public abstract class ModuleBase
    {
        public abstract void Execute();
    }
现在我在另一个项目中实现了一个插件:

public class TestModule : ModuleBase
{
    public static int StaticTest;

    public override void Execute()
    {
        StaticTest = 3; // variable is initialized with some non-default value

        WebHost.CreateDefaultBuilder()
               .UseStartup<Startup>()
               .Build()
               .RunAsync(cancellationTokenSource.Token);
     }
 }
没什么特别的,真的。但是,当我现在实现一个访问我的
StaticTest
变量的控制器时,它的值是0:

public class TestController : ControllerBase
{
    [Route("Test")]
    [HttpGet]
    public ActionResult<int> GetStatics()
    {
        return TestModule.StaticTest;
    }
}
公共类TestController:ControllerBase
{
[路线(“测试”)]
[HttpGet]
公共操作结果GetStatics()
{
返回TestModule.StaticTest;
}
}
如果我放弃插件方法,而是直接从控制台应用程序创建
WebHost
,一切都会按预期工作,控制器返回3

我怀疑MVC在不同的
AppDomain
中启动控制器,但情况似乎并非如此,因为
AppDomain.CurrentDomain.FriendlyName
AppDomain.CurrentDomain.Id
不会更改,并且不会调用
AppDomain.CurrentDomain.DomainUnload


任何想法都是受欢迎的,我现在完全不知所措,我觉得我错过了整个事情的一些基本概念。

您有一个名为
Test
的ivar,您正在访问一个名为
StaticTest
的成员,该成员似乎没有定义。我的假设是您在这个问题中错误地命名了ivar,它应该是
StaticTest
,而不是
Test

基于这种假设,问题是您已经将动态创建的对象强制转换为
ModuleBase
,但是
TestModule
上存在
StaticTest
。因此,除非您强制转换到
TestModule
,否则无法访问
StaticTest
,因为它是在那里定义的

编辑


对不起,我对控制器代码关注不够。真正的问题与上述类似,但与执行有关。您还没有显示调用它的位置,但是我假设您在某处调用它,或者关于为什么静态没有值的答案将非常明显。但是,如果您的实例被键入为
ModuleBase
,它将调用
ModuleBase.Execute()
,而不是
TestModule.Execute()
,即使它实际上是一个
TestModule
实例。只有在使用实际键入为
TestModule
的内容时,才会调用正确的
Execute
override

您有一个名为
Test
的ivar,您正在访问一个名为
StaticTest
的成员,该成员似乎没有定义。我的假设是您在这个问题中错误地命名了ivar,它应该是
StaticTest
,而不是
Test

基于这种假设,问题是您已经将动态创建的对象强制转换为
ModuleBase
,但是
TestModule
上存在
StaticTest
。因此,除非您强制转换到
TestModule
,否则无法访问
StaticTest
,因为它是在那里定义的

编辑


对不起,我对控制器代码关注不够。真正的问题与上述类似,但与执行有关。您还没有显示调用它的位置,但是我假设您在某处调用它,或者关于为什么静态没有值的答案将非常明显。但是,如果您的实例被键入为
ModuleBase
,它将调用
ModuleBase.Execute()
,而不是
TestModule.Execute()
,即使它实际上是一个
TestModule
实例。只有在使用实际键入为
TestModule
的内容时,才会调用正确的
Execute
override

感谢@Chris Pratt指出这一点,我已经相应地编辑了我的问题。在写这篇文章的时候漏掉了。我有一些最小的代码来隔离问题,但是我没有一致地重命名变量。缺少的
Execute
只是在代码块下面格式错误。该变量已初始化,中间未被覆盖。感谢@Chris Pratt指出这一点,我已相应地编辑了我的问题。在写这篇文章的时候漏掉了。我有一些最小的代码来隔离问题,但是我没有一致地重命名变量。缺少的
Execute
只是在代码块下面格式错误。该变量已初始化,并且在两者之间未被覆盖。
到目前为止效果良好。现在我在另一个项目中实现了一个插件:
this。什么意思?你怎么知道execute被调用了?你有日志记录吗?您确定(像真的、真的确定)您引用的StaticTest属性是正确的类型,并且不是基类型上具有类似名称的属性吗?你所描述的似乎是不可能的,所以我假设发生了什么事。@A.Chiesa:我肯定我引用的是来自
TestModule
的静态变量,因为该变量没有在基类型中定义。为了清楚起见,我相应地更新了问题。如果我将
TestModule
包装到控制台应用程序中,并使用
new TestModule().Execute()
运行它,那么一切都会按预期运行。现在的问题是:您如何知道在MVC中调用了
TestModule.Execute
方法?您是否在方法内部记录(到控制台或您使用的任何日志记录工具)?您确定找到的类型是
TestModule
?因为项目是从Visual Studio启动的,所以我只需在
TestModule.Execute
中设置一个断点。我还调查了加载程序中的
类型
(第一个代码序列号)