2009-10-29 66 views
0

StructureMap不喜歡將Nullable類型作爲構造函數參數傳遞。是否有一個原因?有沒有辦法讓這個工作?StructureMap「WithCtorArg」「EqualTo」和可爲空類型

[TestMethod] 
public void Demo() 
{ 
    ObjectFactory.Initialize(x => x.ForRequestedType<TestClass>() 
            .TheDefault.Is.OfConcreteType<TestClass>() 
            .WithCtorArg("param1").EqualTo((byte?)3)); 

//This fails, but works if it's non-nullable 
    var result = ObjectFactory.GetInstance<TestClass>(); 
} 

public class TestClass 
{ 
    public TestClass(byte? param1) 
    { } 
} 

回答

4

根本的問題是,有沒有區別,從CLR的角度來看,可空類型的盒裝(轉換爲Object)實例之間,並且等效的非空類型的(未裝箱)實例。同樣,當您調用類型爲int?的可空類型的GetType()時,返回的類型與常規的int無法區分。請參閱http://msdn.microsoft.com/en-us/library/ms366789.aspx關於此的更多信息。

這種行爲是像StructureMap這樣的代碼的災難處理方法,它使用GetType()在Object-typed參數上詢問類型。因爲StructureMap不知道你的byte?是否實際爲空,所以當StructureMap代碼生成構造函數調用時,代碼將它定義爲常規的byte,它在運行時炸彈,因爲StructureMap將錯誤類型傳遞給構造函數調用。

StructureMap可以解決這個問題,但這些更改是不平凡的。我試着對StructureMap源代碼進行一些調整(例如,從使用Object和GetType()改爲使用接受泛型參數類型的泛型方法,然後可以詢問它是否爲可空類型。需要更多的更改(包括AFAIK,在IL代中需要進行構造函數調用),所以我放棄了。

您可能希望將這一點與最瞭解代碼的結構圖團隊本身聯繫起來。 StructureMap Google Group是一個合理的地方開始。請注意,你的問題之前已經被要求(見this post末),所以我不知道該谷歌集團的響應程度。

但是,StructureMap除非有自我修復,如果我你是我認爲是否包裝g在一個簡單的包裝中刪除類的構造函數中的可空參數。

或者如果你感覺很勇敢,你可以嘗試修復這個問題,通過非常熟悉StructureMap源代碼。 :-)

順便說一句,這裏的地方在StructureMap源發生問題一例:

/// <summary> 
    /// Sets the value of the constructor argument 
    /// </summary> 
    /// <param name="propertyValue"></param> 
    /// <returns></returns> 
    public T EqualTo(object propertyValue) 
    { 
     if(propertyValue.GetType().IsSimple()) 
      _instance.SetProperty(_propertyName, propertyValue.ToString()); 
     else 
     { 
      _instance.SetChild(_propertyName,new LiteralInstance(propertyValue)); 
     } 
     return (T) _instance; 
    } 

通過的PropertyValue參數轉換爲對象,這是不可能的方法來知道這是一個空類型,因爲byte?byte一旦轉換爲Object就無法區分。

0

我在StructureMap源代碼中找到了這段代碼。看起來它不包括可爲空的類型。

protected internal bool IsSimple(Type type) 
{ 
    return type.IsPrimitive || IsString(type) || IsEnum(type); 
} 
+0

原來這個代碼不負責,但我仍然不知道爲什麼這不被支持。 – 2009-10-29 19:27:29