我做类似于你在导入实用程序,写描述了一些东西。我的问题是我不想加载所有的程序集。我只想加载包含请求类型的程序集。
为了实现这一点,我使用了AppDomain.CurrentDomain.AssemblyResolve事件处理程序。
此事件处理程序恰好在AppDomain抛出异常通知未找到程序集之前引发。我执行与Nico在该处理程序中建议的类似的代码并返回所需的程序集。
注意:我有一个名为'任务'(想想导入任务)的子目录,我在那里存储我想在运行时加载的所有程序集。
下面是代码:
var tasks = GetTasks();
var basedir = AppDomain.CurrentDomain.BaseDirectory; // Get AppDomain Path
var tasksPath = Path.Combine(basedir, "Tasks"); // append 'Tasks' subdir
// NOTE: Cannot be factored, relies on 'tasksPath' variable (above).
AppDomain.CurrentDomain.AssemblyResolve += (s, e) => // defined 'AssemblyResolve' handler
{
var assemblyname = e.Name + ".dll"; // append DLL to assembly prefix
// *expected* assembly path
var assemblyPath = Path.Combine(tasksPath, assemblyname); // create full path to assembly
if (File.Exists(assemblyPath)) return Assembly.LoadFile(assemblyPath); // Load Assembly as file.
return null; // return Null if assembly was not found. (throws Exception)
};
foreach (var task in tasks.OrderBy(q => q.ExecutionOrder)) // enumerate Tasks by ExecutionOrder
{
Type importTaskType = Type.GetType(task.TaskType); // load task Type (may cause AssemblyResolve event to fire)
if (importTaskType == null)
{
log.Warning("Task Assembly not found");
continue;
}
ConstructorInfo ctorInfo = importTaskType.GetConstructor(Type.EmptyTypes); // get constructor info
IImportTask taskInstance = (IImportTask)ctorInfo.Invoke(new object[0]); // invoke constructor and cast as IImportTask
taskInstances.Add(taskInstance);
}
// rest of import logic omitted...
这里唯一的风险是如此有正确的下降有非托管的DLL的风险就会加载任何.dll文件? – 2012-07-15 11:53:20
是的,这是正确的。我认为,他能够将错误处理纳入必要的程度。但这取决于确切的情况。 – 2012-07-15 11:57:34