2016-03-07 57 views
3

我正在尋找一種方法來注入一個日誌記錄對象,它將log4net記錄器封裝到使用MEF的各種對象中。我現在遇到的問題是日誌對象需要它所屬的對象的類型。我可以通過在包含對象的構造函數中設置日誌記錄對象的type屬性來解決此問題,但是這留下了在開發人員中設置類型的責任,並且沒有編譯時間限制,我可以考慮強制執行此操作。使用MEF注入對象與關於目標對象的信息

我有一種方法來指定,當記錄對象由MEF生成並注入時,其構造函數參數設置爲注入的目標類的類型?

我的記錄器實現一個接口的具體實施的本的

public interface ILogger 
{ 
    Type Type { get; } 
} 

一個例子是

[Export(typeof(Ilogger))] 
public class SimpleLogger : ILogger 
{ 
    public SimpleLogger(Type typeOfObjectToLogFor) 
    { 
     this.Type = typeOfObjectToLogFor 
    } 

    public Type Type { get; } 

    public void Info(string message) 
    { 
     //log the messsage including the type information 
    } 
} 

並且它不使用MEF作爲目前消耗:

public class ExampleObject 
{ 
    private readonly ILogger logger = new SimpleLogger(typeof(ExampleObject)); 

    public ExampleObject(){} 

    public void MethodThatLogs() 
    { 
     logger.Info("MethodThatLogs called"); 
    } 
} 

和我想要做的是使用構造函數注入注入它:

public class ExampleObject 
{ 
    private readonly ILogger logger; 

    [ImportingConstructor] 
    public ExampleObject(Ilogger injectedLogger) 
    { 
     logger = injectedLogger; 
    } 

    public void MethodThatLogs() 
    { 
     logger?.Info("MethodThatLogs called"); 
    } 
} 

我能做到這一切與懶惰評價反映,但感覺喜歡的事,應該有可能從一個體面的DI容器,並希望這意味着,MEF將支持它,凸輪誰能幫助?

回答

3

默認情況下,指定[Export]屬性,你設置的PartCreationPolicyShared,這意味着容器將爲您導出一個單 - 的記錄。

但我建議你不要導出類,而是要接受一個參數併爲你創建記錄器的工廠方法。

class LoggerFactory 
{ 
    [Export("GetLogger")] 
    public ILogger GetLogger(Type type) 
    { 
     return new SimpleLogger(type); 
    } 
} 

class ExampleObject 
{ 
    private readonly ILogger logger; 

    [ImportingConstructor] 
    public ExampleObject([Import(ContractName = "GetLogger", AllowDefault = true)]Func<Type, ILogger> loggerCreator) 
    { 
     logger = loggerCreator?.Invoke(this.GetType()); 
    } 
}