Caller context

Dec 24, 2009 at 6:27 AM

Is it possible to get the context when the object is being created? I would like to do something like Log4Net declaration. Usually we declare 

 

private readonly ILog logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().ReflectedType)

It would be nice if I can wrap Log4Net around and declare something like this...

 

[PartCreationPolicy(CreationPolicy.NonShared)]
[InjectedWithCallingType]
[Export(typeof(ILogService)]
public class LogService : ILogService {
    private readonly Logger logger;

    public LogService(Type callingType)
    {
         logger = LogManager.GetLogger(callingType);
    }
  
    public void Debug(string message)
    {
         logger.Debug(message);
    }
}


[Import]
private ILogService logService;

 

 

 

 

 

 

Jan 1, 2010 at 10:54 AM

There is no magic way for LogService to get access to the type that imported it. It is possible to do it in a custom export provider, but I wouldn't recommend it as it is not trivial, or documented how you would do it.

Instead what I would recommend is having the LogService have a SetCallingType method. Then when the importer imports ILogSerivce, it will just call SetCallingType and pass in it's type. For example.

[PartCreationPolicy(CreationPolicy.NonShared)]
[Export(typeof(ILogService)]
public class LogService : ILogService {
    private readonly Logger logger;

    public LogService()
    {
             }

    public void SetCallingType(Type callingType) {
      logger = LogManager.GetLogger(callingType);
    }
  
    public void Debug(string message)
    {
         logger.Debug(message);
    }
}

[Export]
public class UsesLogService {

  private ILogService _logService;

  [Import]
  private ILogService logService {
    get{return _logService;}
    set{
      value.SetCallingType(this.GetType());
      _ logService = value;
    }
  }
}

The UsesLogService part above imports ILogService as a property rather than a field. In the setter it calles the SetCallingType method on the log service passing in it's type.
You could also still use a FieldImport, but in that case you'll want the part to implement IPartImportsSatisfiedNotification and put then call _logService.SetCallingType in the OnImportsSatisfied method of that interface.
Thanks
Glenn
Jan 4, 2010 at 1:59 AM

Glenn,

Thank you very much. Quite interesting hack :)

Jun 8, 2013 at 8:42 PM
Sorry to resurrect this thread, but it is better than writing a duplicate.

Seeing how Glenn's response was written in 2010 for MEF1, I am hoping the MEF team has come up with a user story for this scenario in MEF2.

Please see my StackOverflow question: http://stackoverflow.com/questions/17002870/how-to-use-mef2-to-do-import-log4net-ilog