2013-10-17 95 views
1

我正在使用依賴注入,並且遇到了一些我找不到的東西。我有一個需要一個通用的記錄基類:依賴注入,繼承和泛型

public class BaseClass 
{ 
    public BaseClass(ILogger<BaseClass> logger) 
    { 
     // code here 
    } 
} 

然後,我有一個類繼承也需要通用的記錄:

public class SubClass : BaseClass 
{ 
    public SubClass(ILogger<SubClass> logger) 
    { 
     // code here 
    } 
} 

的問題是,這並不與消息編譯; BaseClass不包含接受0個參數的構造函數

這將是很容易解決,如果我能做到這一點:

public SubClass(ILogger<SubClass> logger) : base(logger) 

的問題是,這是不合法的或者因爲ILogger<SubClass>不是ILogger<BaseClass>一個實例(它不與編譯最好的超載匹配...有一些無效參數)。

一個可能的解決方案: 我想我不必使用構造函數注入,而是使用DependencyResolver

問題:肯定有人提出過這個問題嗎?是否有可能使用構造函數注入?如果是這樣,我該怎麼辦?

注:在當前項目中,我使用StructureMapfor MVC4),但我認爲,這裏的工具是稍微無關。

+1

如果你發現自己注入了相同的依賴到不同的類來做同樣的事情,你可能想看看攔截。 –

+0

@FacioRatio感謝您的洞察。之後,我閱讀了http://programmers.stackexchange.com/questions/139111/interception-vs-injection-a-framework-architecture-decision,這非常有趣。正如我在其他地方指出的那樣,'ILogger '已經通過DI使用在許多不同的解決方案和項目中,但對於未來的解決方案,這當然值得考慮。 – Halvard

+0

裝飾很不錯,但是當你結束了許多做同樣事情的裝飾器時,是時候進行截取了。請參閱:http://simpleinjector.codeplex.com/wikipage?title=Advanced-scenarios#Interception –

回答

2

你能更改記錄器接口爲:

interface ILogger<out T> where T : BaseClass 
+0

+1我必須承認,當我以這種方式使用'out'時,我必須真正考慮發生了什麼。它確實解決了編譯問題,我確實認爲這個類被使用的方式,這是解決問題的有效方法。儘管我的思想並沒有真正地將自己包裹在使用它的後果中,但我將它標記爲正確的答案。 – Halvard

1

發生這種情況是因爲ILogger<SubClass>不是ILogger<BaseClass>的子類,所以編譯器認爲你編寫了一個新的構造函數。如果你寫了這個隱式地相當於

public class SubClass : BaseClass 
{ 
    public SubClass(ILogger<SubClass> logger) 
     : base() // since base class does not have a constructor 
       // with no arguments, you will get the error 
    { 
     // code here 
    } 
} 

所以你的問題不是完全依賴於依賴注入。它更多的是關於你的架構。

+0

我接受這可能是一個體繫結構問題(並且我理解錯誤消息),但是您是否說我不能通過這個泛型類的構造函數使用DI('Ilogger ')? – Halvard

+0

DI只是一種自動化手動操作的工具。如果你可以編譯你的代碼,那麼你可以使用DI :)我想,你是否真的需要'ILogger'有一個通用參數? –

+0

「ILogger」在太多的項目中被用來將其改爲不通用。這是舊的遺留代碼,很好用(和有用)。無論如何感謝您的輸入! – Halvard

1

你可以在你的BaseClass添加參數的構造函數這將調用參數的構造函數,並把它傳遞一個手動解決​​實例。事情是這樣的:

public BaseClass() 
    : this(ResolveLogger()) 
{ 
} 

private static ILogger<BaseClass> ResolveLogger() 
{ 
    // resolve the instance manually and return it 
} 

這樣,如果BaseClass類型的實例得到解決,它將使用參數的構造函數,並注入解決ILogger<BaseClass>實例。但是,如果派生類已解析,則此派生類將調用無參數BaseClass()構造函數,並且ILogger<BaseClass>將手動解析。

+0

+1這將是解決問題的有效方法。我想嘗試解決它,而不必手動解決記錄器,所以我給另一個答案正確答案複選標記。 Thnaks爲您提供幫助! – Halvard