为什么模块初始化器不触发接口使用?
本文关键字:接口 模块 初始化 为什么 | 更新日期: 2023-09-27 18:06:40
代码
我有两个集合
"AssemblyWithClassAndModuleInit"包含一个类
public class MyBaseClass
{
}
"AssemblyWithInterfaceAndModuleInit"包含一个接口
public interface MyInterface
{
}
都包含一个模块初始化式
public static class ModuleInitializer
{
public static void Initialize()
{
Environment.SetEnvironmentVariable("ModuleInitializer", "true");
}
}
测试"AssemblyWithClassAndModuleInit"(注意MyBaseClass
用作ClassTests
的基础)
[TestFixture]
public class ClassTests : MyBaseClass
{
[Test]
public void EnsureModuleInitIsCalled()
{
Assert.AreEqual("true", Environment.GetEnvironmentVariable("ModuleInitializer"));
}
[Test]
public void EnsureAssemblyIsLoaded()
{
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
Assert.IsTrue(assemblies.Any(x => x.GetName().Name == "AssemblyWithClassAndModuleInit"));
}
}
测试"AssemblyWithInterfaceAndModuleInit"(注意MyInterface
用作InterfaceTests
的接口)
[TestFixture]
public class InterfaceTests : MyInterface
{
[Test]
public void EnsureModuleInitIsCalled()
{
Assert.AreEqual("true", Environment.GetEnvironmentVariable("ModuleInitializer"));
}
[Test]
public void EnsureAssemblyIsLoaded()
{
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
Assert.IsTrue(assemblies.Any(x => x.GetName().Name == "AssemblyWithInterfaceAndModuleInit"));
}
}
唯一失败的测试是InterfaceTests.EnsureModuleInitIsCalled
。
为什么呢?InterfaceTests
实现MyInterface
的事实不应该导致模块初始化器运行吗?
如何注入模块初始化器
我正在使用IL编织。特别是https://github.com/Fody/ModuleInit
它检测到
public static class ModuleInitializer
{
public static void Initialize()
{
//Init code
}
}
加上
static <Module>()
{
ModuleInitializer.Initialize();
}
<标题> 更新- 作为旁白,如果我添加一个字段
Type interfaceType = typeof(MyInterface);
到InterfaceTests
,那么所有的测试都通过了。 - 编码是针对。net 4.5 完成的
这是一个带有单元测试的reppro https://github.com/SimonCropp/Experiments/tree/master/ModuleInitRepro
标题>标题>标题>一个明显的潜在相关的事情:您的测试类派生自prod程序集中的基类。因此,创建测试类的实例需要调用基类中的构造函数(隐式地),这意味着需要完全加载和初始化基类,因此需要初始化程序集。
将其与接口版本进行比较-在测试类中实现prod-assembly接口的事实在执行时实际上是无关的,因为您没有做任何需要接口的事情。
我怀疑如果你有:
public void Foo(MyInterface x)
{
}
[Test]
public void EnsureAssemblyIsLoaded()
{
Foo(this);
... assertions ...
}
则可以初始化程序集。如果您在接口中声明了任何方法,并且从Foo
调用了其中一个方法,那么我肯定希望程序集被初始化。