I was searching for a way to get all active log4net logfiles (if any) at runtime without adding a reference to the project.
This is the solution I came up with:
private static IEnumerable<AbstractReportInformation> GetLog4NetLogfiles()
{
var type = Type.GetType("log4net.LogManager,log4net");
if(null == type)
return new List<AbstractReportInformation>();
dynamic[] repositories = type.GetMethod("GetAllRepositories").Invoke(null, null) as dynamic[];
IEnumerable<FileInfo> files = repositories
.SelectMany<dynamic, dynamic>(repos => repos.GetAppenders())
.Where(appender => Type.GetType("log4net.Appender.FileAppender,log4net").IsAssignableFrom(appender.GetType()))
.Select(appender => new FileInfo(appender.File));
return files.Select(
file => new FilesystemInformation(file)).Cast<AbstractReportInformation>().ToList();
}
It makes use of the dynamic
keyword instead of doing it all with reflection.
- Are there any obvious errors in my code?
- Are there better ways to achieve the same result?
I feel a bit unsure about leaving the safety of the otherwise strongly typed language / framework.
Update to explain why no references shall be used / why dynamic
is used
The above code is used to "detect" whether log4net is present and then gathers the logfiles. The same will later be implemented for NLog and possibly other frameworks of that sort. The project I'm using this code in is a application health monitoring framework and I don't want to add a lot of references.