如果你只是想要延迟加载程序集,那么你可以参考
这个问题的部分解决方案。你不需要获取该解决方案中检索到的所有信息,可能只需要合同名称、程序集名称以及该部件是否正在导出或导入合同。然后,你可以编写一个目录,根据需要加载程序集,例如像这样:
public sealed class DelayLoadingCatalog : ComposablePartCatalog
{
private readonly List<Tuple<string, string>> m_Plugins
= new List<Tuple<string, string>>();
private readonly Dictionary<string, AssemblyCatalog> m_Catalogs
= new Dictionary<string, AssemblyCatalog>();
public DelayLoadingCatalog(IEnumerable<Tuple<string, string>> plugins)
{
m_Plugins.AddRange(plugins);
}
public override IEnumerable<Tuple<ComposablePartDefinition, ExportDefinition>> GetExports(ImportDefinition definition)
{
var partsToLoad = m_Plugins
.Where(t => t.Item1.Equals(definition.ContractName));
foreach (var part in partsToLoad)
{
if (!m_Catalogs.ContainsKey(part.Item2.Name))
{
var assembly = Assembly.Load(new AssemblyName(part.Item2.Name));
m_Catalogs.Add(part.Item2.Name, new AssemblyCatalog(assembly));
}
}
return m_Catalogs.SelectMany(p => p.Value.GetExports(definition));
}
public override IQueryable<ComposablePartDefinition> Parts
{
get
{
throw new NotImplementedException();
}
}
}
您可以像这样使用它。
class Program
{
public void Init()
{
var domainSetup = new AppDomainSetup
{
ApplicationBase = Directory.GetCurrentDirectory(),
};
var scanDomain = AppDomain.CreateDomain(
"scanDomain",
null,
domainSetup);
var scanner = scanDomain.CreateInstanceAndUnwrap(
typeof(MyScanner).Assembly.FullName,
typeof(MyScanner).FullName) as MyScanner;
var plugins = scanner.Scan(myPluginsPath);
AppDomain.Unload(scanDomain);
var catalog = new DelayLoadingCatalog(plugins);
var container = new CompositionContainer(catalog);
container.ComposeParts(this);
}
[Import("MyCoolExport")]
public object MyImport
{
get;
set;
}
}
示例DelayLoadCatalog并不太聪明,因为它将继续在Tuple列表中进行搜索。优化代码并不难。例如,你可以检查是否已加载了所有程序集,并在那一点停止搜索该列表。
ReflectionModelServices
API,一切都是懒加载的。 对于我的要求来说,这似乎是最好的方式。 我希望我有时间回答这个问题,并展示出我已经完成的工作。 再次感谢! - Adi Lester