2016-03-07 55 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()); 
    } 
}