我们正在使用Catel.MVVM开发GUI插件框架。 应使用“ServiceLocatorRegistration”属性动态加载单个插件。
实施例:
[ServiceLocatorRegistration(typeof(IInitializable), ServiceLocatorRegistrationMode.SingletonInstantiateWhenRequired, "SamplePlugin")]
在我们的引导程序中,我们将所有插件程序集加载到默认的AppDomain中:
Catel.Windows.Controls.MVVMProviders.Logic.UserControlLogic.DefaultSkipSearchingForInfoBarMessageControlValue = true;
Catel.Windows.Controls.MVVMProviders.Logic.UserControlLogic.DefaultCreateWarningAndErrorValidatorForViewModelValue = false;
IoCConfiguration.DefaultServiceLocator.AutoRegisterTypesViaAttributes = true;
IoCConfiguration.DefaultServiceLocator.CanResolveNonAbstractTypesWithoutRegistration = true;
foreach (
var file in
BaseDirectory.GetFiles("*.dll", SearchOption.AllDirectories)
.Where(f => IsNetAssembly(f.FullName))
.Where(f => !f.FullName.EndsWith("resources.dll"))
.AsParallel())
{
try
{
var asm = Assembly.ReflectionOnlyLoadFrom(file.FullName);
}
catch { }
}
然后我们尝试通过调用
来初始化它们var initializables = ServiceLocator.Default.ResolveTypes();
foreach(var initializable in initializables)
initializable.Initialize();
但即使我们在AppDomain中加载了插件程序集,我们也不会获得具有ServiceLocatorRegistration属性的所有Classes。
有没有解决所有具有如上设置的示例属性的类? 提前谢谢!
答案 0 :(得分:1)
我自己解决了这个问题。错误可能是行
var asm = Assembly.ReflectionOnlyLoadFrom(file.FullName);
用AppDomain.CurrentDomain.LoadAssemblyIntoAppDomain(file.FullName);
替换此行后,一切都按预期工作。
感谢Geert指向正确的方向!
答案 1 :(得分:0)
问题可能是因为包含使用注册的类型的程序集尚未加载到AppDomain中。您可以考虑以下几点:
1)使用AppDomainExtensions.PreloadAssemblies
2)以某种方式使用类型(如Console.WriteLine(typeof(TypeFromAssembly).FullName))
我不建议使用第二个,因为它违反了您的插件架构。