Я пишу программу, которая является контейнером для других, небольших программ.Он загружает свои модули через Assembly.Load, находит типы, реализующие IModule, и создает их экземпляры.
В WPF MainWindow у меня есть RoutedViewHost, который будет отображать все.
В моем AppBoostrapper у меня естьследующее:
private ReactiveList<IModule> LoadModules(IMutableDependencyResolver resolver)
{
var modules = ModuleLoader.Load(ModulesDirectory);
// var modules = new IModule[] { new SampleModuleClass(), }; // this works perftectly!
foreach (var module in modules)
{
try
{
module.RegisterDependencies(this, resolver);
}
catch (Exception e)
{
Log.Error(e, "Could not register dependecies for module " + module.Name);
}
}
Log.Debug("Modules loaded: " + string.Join(", ", modules.Select(x => x.Name)));
return new ReactiveList<IModule>(modules);
}
Затем в моем примере модуля:
public void RegisterDependencies(IMainScreen screen, IMutableDependencyResolver resolver)
{
_screen = screen;
_resolver = resolver;
resolver.Register(() => new SampleView(), typeof(IViewFor<SampleViewModel>));
resolver.Register(() => new GetNameDialogView(), typeof(IViewFor<GetNameDialogViewModel>));
Log.Debug("Dependecies registered");
}
Кроме того, у каждого модуля есть свой MainViewModel, который отображается RoutedViewHost при выборе модуля.
К сожалению, это не работает.Я получаю следующую ошибку:
ReactiveUI.RoutedViewHost ОШИБКА Не удалось найти IPlatformOperations.Этого никогда не должно случиться, ваш преобразователь зависимостей не работает
ModuleLoader.Load работает так:
public static IModule[] Load(string path)
{
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
Log.Error("No modules directory found - creating");
return new IModule[0];
}
var moduleTypes = GetTypes(path);
return moduleTypes.Select(MakeInstance).Where(x => x != null).ToArray();
}
private static IModule MakeInstance(Type type)
{
try
{
var module = type.GetConstructor(new Type[] { })?.Invoke(new object[] { }) as IModule;
if (module != null)
{
Log.Info("{0} module succesfully instatiated", module.Name);
return module;
}
Log.Error("Could not instantiate {0}", type.FullName);
return null;
}
catch (Exception exception)
{
Log.Error(exception, "Exception during instatiating {0}", type.FullName);
return null;
}
}
private static List<Type> GetTypes(string path)
{
var di = new DirectoryInfo(path);
var moduleTypes = new List<Type>();
foreach (var dir in di.GetDirectories())
{
FileInfo[] files = dir.GetFiles("*.dll");
foreach (var file in files)
{
Assembly newAssembly = Assembly.LoadFile(file.FullName);
Type[] types = newAssembly.GetExportedTypes();
foreach (var type in types)
{
if (type.IsClass && !type.IsAbstract && (type.GetInterface(typeof(IModule).FullName) != null))
{
moduleTypes.Add(type);
Log.Debug("Loaded {0} type", type.Name);
}
}
}
}
return moduleTypes;
}
Нет ошибки, если я просто создаю экземпляр вместо загрузкисборка.Если это важно, SampleModule также использует ReactiveUI.
Я пытался добавить Locator.CurrentMutable.InitializeReactiveUI();
в разных местах (конструктор MainWindow, конструктор приложения, статический конструктор модуля), но ничего не помогло.Есть идеи?
РЕДАКТИРОВАТЬ: если это важно, MainWindow - это MetroWindow от mahapps.metro
EDIT2:
Я пытался зарегистрировать PlatformOperations, как @Wouter предложил для:
`var iPlatformOperations = Type.GetType (" ReactiveUI.IPlatformOperations, ReactiveUI, Версия = 7.4.0.0, Culture = нейтральный, PublicKeyToken = null ");
resolver.Register (() => new PlatformOperations (), iPlatformOperations); `
как до загрузки модуля, так и после, но ничего не меняется.