2012-12-07 64 views
0
public class A 
{ 
    public X x { get; set; } 
} 

public class B 
{ 
    public X x { get; set; } 
} 

public class X 
{ 
    public X(object owner) { /* ... */ } 
} 

基本上,如果類AB在溫莎註冊我希望能夠解決這樣一種方式,它得到它所需的類的實例X依賴。在滿足屬性依賴性之前是否可以獲取正在解析的組件的實例?

在明碼它看起來像:

var a = new A(); 
var x = new X(a); 
a.X = x; 

有沒有辦法做到這一點的溫莎,也許通過一些擴展機制?


看起來甚至對我有些抓狂的問題,所以這裏是一些背後的動機:

上面例子中的XITracer這是一個代理TraceSource,它是將信息的某些位到每個跟蹤的消息,即所有者的唯一ID和它的類型(現在它只是ID - 這就是爲什麼這個問題 - 我無法訪問該實例並在其上調用GetType())。

一個簡單的例子,使其更加清晰。假設你有一些服務IService,並想以最不干擾的方式添加跟蹤。但是在應用程序中可能有十幾個這種服務的實例,所以在跟蹤中你想通過ID /類型區分它們。如果類從容器中所接納的示蹤劑,只是寫郵件有需要的時候,沒有ID的思維,這將是很好的具體TraceSource

我已經有了一定的基礎設施,可以讓我寫這樣的:

[TracedTo("NameOfTheTraceSource")] 
public class Service : IService 
{ 
    public ITracer Tracer { get; set; } 
} 

而且Windsor正確解析爲Tracer是它自己的(與其他對象不共享)ITracer實例指向TraceSource的名稱NameOfTheTraceSource。此外,如果我將traceAllMethods = true添加到屬性 - Windsor將自動添加攔截器,該攔截器將通過相同的Tracer記錄此實例上的每個方法調用(並且只有在相應的TraceSource配置了一些偵聽器時纔會這樣做 - 我們不必支持添加他們在飛行中)。這真是太棒了,因爲它不需要任何東西來自Service的開發人員,並且在不需要時不會降低性能。所以我正在努力使這更加方便:)

+0

我認爲服務覆蓋將工作 - 或者可能是一個子依賴解析器。你看過那些嗎? – PatrickSteele

+0

@Patrick我目前的實現是基於能夠解析ITracer實例的子解析器。不幸的是,它只能訪問ComponentModel而不是組件實例。或者也許有一些技巧我不明白?你能提供一些基本的代碼草圖嗎? –

+0

我已經閱讀了幾次,而且我不太清楚你到底需要什麼 - 或者它沒有工作。您能否通過一個代碼示例更新問題,說明您如何設置Windsor以及哪些部分無法正常工作。你是否解決了錯誤的實例?什麼邏輯確定「所有者」的「正確」實例是針對每個「X」的? – PatrickSteele

回答

1

好的,我認爲你在這裏想要的是一個設施。這裏有一個簡單的(沒有錯誤檢查)可能是你在找什麼(或者至少點你在正確的方向):

public class XFacility : AbstractFacility 
{ 
    protected override void Init() 
    { 
     this.Kernel.ComponentCreated += KernelOnComponentCreated; 
    } 

    private void KernelOnComponentCreated(ComponentModel model, object instance) 
    { 
     var props = 
      instance.GetType().GetProperties().Where(p => p.CanWrite && p.PropertyType == typeof (X)); 
     if (props.Any()) 
     { 
      var pi = props.First(); 
      pi.SetValue(instance, new X(instance), null); 
     } 
    } 
} 

現在確保你面前設施添加到容器做任何解決:

var container = new WindsorContainer(); 
container.AddFacility<XFacility>(); 
container.Register(Component.For<A>(), 
        Component.For<B>() 
    ); 

var a = container.Resolve<A>(); 
相關問題