0

我们正在使用 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 属性的类。

是否有任何方法可以解决所有具有上述示例属性设置的类?提前致谢!

4

2 回答 2

1

自己解决了这个问题。错误可能是这条线

var asm = Assembly.ReflectionOnlyLoadFrom(file.FullName);
用一切替换这条线后,
AppDomain.CurrentDomain.LoadAssemblyIntoAppDomain(file.FullName);
一切都按预期工作。感谢 Geert 指出了正确的方向!

于 2014-01-15T08:49:24.287 回答
1

问题可能是因为包含使用注册的类型的程序集尚未加载到 AppDomain 中。您可以考虑以下几点:

1) 使用AppDomainExtensions.PreloadAssemblies

2)以某种方式使用类型(如 Console.WriteLine(typeof(TypeFromAssembly).FullName))

我不推荐第二个,因为它违背了您的插件架构。

于 2014-01-13T15:10:19.910 回答