I am working on some software that supports the use of Reporting modules. Basically we don’t want to ship ALL reports by default as it just creates unnecessary bloat so I am looking for an efficient way to check the present exe and dll for valid modules that can by dynamically added at runtime. So far I’ve experimented with setting a custom Attribute in AssemblyInfo and used at as a flag like so:
private void GetReportModules() {
try {
var dlls = Directory.GetFiles(Directory.GetCurrentDirectory()).Where(x => Path.GetExtension(x) == ".dll" || Path.GetExtension(x) == ".exe");
dlls = dlls.OrderBy(x => Path.GetFullPath(x)).Where(x => {
try {
return null != System.Reflection.Assembly.LoadFrom(x);
} catch (Exception) {
Console.WriteLine("Skipping {0} - does not load using reflection.", Path.GetFileName(x));
return false;
}
});
foreach (var dll in dlls) {
System.Reflection.Assembly assembly = System.Reflection.Assembly.LoadFrom(dll);
object[] attributes = assembly.GetCustomAttributes(typeof(ReportNameAttribute), false);
if (attributes.Count() > 0) {
// dynamically include the assembly as a menu item
}
}
} catch (Exception ex) { throw new GenericException(ex); }
}
The problem being that I literally have to load every dll and exe twice which doesn’t seem very efficient. Can anyone suggest a way that they’ve accomplished something similar to this before or a way to improve what I’m doing?
It would be seriously awesome if I could check the Attributes without needing to first load the Assembly.
Reflection has it’s cost. usually, it’s not too expensive if you do it once (remember to cache the results. if they’re need to be refreshed every now and then, you can use timer for this).
If you don’t want to load all the assemblies and check, you can use configuration file where user must explicitly define what should be loaded.
You can also set a special folder that should include only dll’s that are relevant for this thing, by definition – anything in this folder would be something you’d like to load.