2015-06-12 102 views
2

我在我的MVC應用程序,它工作正常以下代碼。城堡溫莎註冊組件匹配相同的服務

container.Register(Component.For<CountryServiceBase>() 
    .ImplementedBy<CountryService>() 
    .LifestylePerWebRequest()); 

溫莎城堡創建一個組件

CountryService/CountryServiceBase 

我這裏控制器得到一個實例化對象:

public class MyController : MainController 
{ 
    public CountryServiceBase CountryService {get; set;} // instantiate by Ioc : OK 

我的問題是,我有很多的類註冊。因此,使用溫莎城堡我做了以下內容:

container.Register(
    Types 
    .FromAssemblyNamed("mynamespace") 
    .BasedOn(typeof(ServiceBase<>)) 
    .WithService.Base() 
    .LifestylePerWebRequest()); 

溫莎城堡創建我的部件

CountryService/ServiceBase<Country> 
CountryServiceBase/ServiceBase<Country> 

但我的MVC應用程序等待一個CountryService/CountryServiceBase,我不知道如何指定溫莎城堡是它可以匹配CountryServiceBase到CountryService作爲這兩個類(其中一個是抽象類)繼承ServiceBase

它甚至有可能嗎?

注:我發佈了一個類似的問題,但我的調查導致更準確的一個,所以我刪除了舊的。

+0

嘗試更改'公共CountryServiceBase CountryService {get;設置;}'通過'公共ServiceBase CountryService {get;設置;}' –

+0

它會工作,但在抽象類CountryServiceBase中,我有幾個聲明的方法。否則它會起作用。 – AMS

+0

也許'BasedOn(typeof(CountryServiceBase))'? –

回答

0

如果您CountryServiceBase是抽象類,使用Classes代替Types應有助於避免在基類註冊(見here):在另一方面

類預過濾器的類型只考慮非抽象類

然而,它並不像你能避免在您的註冊提CountryServiceBase,也許使用OrBasedOn(CountryServiceBase)那麼你的實施將是一個既可以是ServiceBase<>也可以是CountryServiceBase

0

您可以使用反射來獲取所有從您的serviceBase繼承的類。 你可以找到一個方法來做到這一點here

然後你可以實現上面的代碼來實例化所有的服務。

+0

這可能是一個想法。我會等待賞金完成,但我喜歡這個解決方案,因爲我可以添加服務,而無需在我的項目中創建它們時逐一註冊。 – AMS

1

通常services是接口。這就是爲什麼AllInterfaces()適用於其他人。

如果你檢查API,你會發現Select()方法,可以很容易地使用。

如果沒有上面的選項適合你,你可以提供自己的 選擇邏輯的委派,並將其傳遞給WithService.Select() 方法。

所以註冊碼可能是以下幾點:

container.Register(Types.FromThisAssembly() 
     .BasedOn(typeof(ServiceBase<>)) 
     .WithService.AllInterfaces() 
     .WithService.Select((t, b) => t.BaseType != null 
       ? new[] { t.BaseType } 
       : new Type[0]) 
     .LifestylePerWebRequest()); 

該解決方案是相當快的和骯髒的,但至少它可以解決您的問題。