2013-03-29 42 views
1

代碼

所以我有兩個組件爲什麼沒有一個模塊初始化火的接口使用

「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 
    } 
} 

如果我添加一個字段Type interfaceType = typeof(MyInterface);InterfaceTests,那麼所有的測試都通過了一旁補充說這

static <Module>() 
{ 
    ModuleInitializer.Initialize(); 
} 

更新

  • 作爲。
  • 編碼是針對.NET 4.5

全部來源

這裏所做的是一個單位的攝製測試https://github.com/SimonCropp/Experiments/tree/master/ModuleInitRepro

+0

可能是重要的,何況你正在使用的CLR版本。 – leppie

+0

你的問題根本沒有提到Fody - 大概是這個模塊初始化類做什麼的魔法? (否則,我不清楚它做了什麼......) –

+0

這個例子有點令人困惑。也許是更好的做這樣的事情: VAR ifacetype = typeof運算(MyInterface的); Assert.AreEqual(「true」等); 這使得您可以更清楚地看到,當您首次使用某個模塊類型時,您希望模塊初始化程序能夠運行。 –

回答

0

一個明顯的潛在相關的事情:你的測試類的基類中派生產品組裝。因此,創建測試類的實例需要調用基類中的構造函數(隱式地),這意味着基類需要被完全加載和初始化,因此程序集需要被初始化。

將其與您的接口版本進行比較 - 在​​測試類中實現prod-assembly接口的事實在執行時是無關緊要的,因爲您沒有做任何需要接口的事情。

懷疑,如果你有:

public void Foo(MyInterface x) 
{ 
} 

[Test] 
public void EnsureAssemblyIsLoaded() 
{ 
    Foo(this); 
    ... assertions ... 
} 

那麼可以初始化組件。如果你有在接口中聲明的任何方法,你叫這些方法之一從Foo,那麼我肯定會想到要初始化的組件。