2013-06-25 33 views
3

我想使用自動混合來創建對象圖,其中的子對象具有對父對象的引用。例如:如何使用自動混合自動設置子對象中的父對象

class A 
{ 
    public List<B> Children { get; set; } 
} 

class B 
{ 
    public A Parent { get; set; } 
} 

我試圖讓一個處理一個遞歸行爲,但我不知道如何發出父對象的屬性的內容。

public class AutoParentOnRecursionBehavior : ISpecimenBuilderTransformation 
{ 
    public ISpecimenBuilder Transform(ISpecimenBuilder builder) 
    { 
     if (builder == null) 
      throw new ArgumentNullException("builder"); 

     return new RecursionGuard(builder, new AutoParentOnRecursionHandler()); 
    } 
} 

public class AutoParentOnRecursionHandler : IRecursionHandler 
{ 
    public object HandleRecursiveRequest(
     object request, 
     IEnumerable<object> recordedRequests) 
    { 
     object handleRecursiveRequest = recordedRequests.First(x => x.Equals(request)); 
     return .... 
    } 
} 

謝謝。

編輯: 我想通用的方式,而不必指定類型A和B甚至屬性兒童。 對於包含對象的屬性類型的所有屬性,請將它們設置爲父對象。換言之,觸發遞歸守護的類型的所有屬性都將它們設置爲創建層次結構中的最後一個對象。

+2

相關http://stackoverflow.com/questions/17087788/create-recursive-tree-with-autofixture –

+2

您可以更改類的API嗎?這裏提出的設計不僅對AutoFixture來說很難處理,而且對於您和您的團隊成員而言,一般來說這將是一個永久的痛苦來源。 –

回答

2

我的回答假設

  1. B.Parent應該null如果你直接創建B
  2. B.Parent應該設置爲包含它的實例A,如果您創建A

這可以用下面的相當簡單的自定義使用PostProcessorFor時可以實現:

fixture.Customize<B>(c => c.Without(x => x.Parent)); 
fixture.PostProcessorFor<A>(a => { foreach(var b in a.Children) b.Parent = a; }); 

一些斷言說明結果:

var b = fixture.Create<B>(); 
Assert.Null(b.Parent); 

var a = fixture.Create<A>(); 
Assert.True(a.Children.All(b => ReferenceEquals(b.Parent, a))); 
+0

感謝您的回答,我可以肯定地使用它,但我想到了更通用的方式,而不必指定類型A和B甚至屬性Children。對於包含對象的屬性類型的所有屬性,將它們設置爲父對象。換言之,觸發遞歸守護的類型的所有屬性都將它們設置爲創建層次結構中的最後一個對象。 – hokkos

+1

@hokkos:對於類型爲* other *的屬性,觸發層次結構中最後一個對象的遞歸警衛屬性如何? 'A.兒童(B型) - > B.兒童(C型) - > c.GrandFather(A型)' –