我正在尝试创建一个简单的插件系统,其中插件在应用程序启动时从.dll文件动态加载并显示在UI中。
https://css-tricks.com/examples/FullPageBackgroundImage/progressive.php似乎正是我正在寻找的。它使用MEF加载插件。我尝试创建一个简单的项目并按照说明操作。我的解决方案具有以下结构:
MefTest.SDK
而非插件)IPlugin.cs
和IPluginViewModel.cs
以及从应用程序目录加载插件的Engine.cs。MefTest.SDK
)MefTest.SDK
)public interface IPlugin
{
IPluginViewModel ViewModel { get; }
ResourceDictionary View { get; }
string Title { get; }
}
public class Engine
{
[ImportMany]
private IEnumerable<IPlugin> plugins { get; set; }
public async Task<ObservableCollection<IPlugin>> GetPlugins()
{
try
{
var folder = AppDomain.CurrentDomain.BaseDirectory;
var catalog = new AggregateCatalog();
//catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
catalog.Catalogs.Add(new DirectoryCatalog(folder));
var container = new CompositionContainer(catalog);
container.ComposeParts(this);
var result = new ObservableCollection<IPlugin>();
foreach (var p in plugins)
{
result.Add(p);
}
return result;
}
catch (Exception ex)
{
//I get the exception here...
var t = ex;
throw;
}
}
}
[Export(typeof(IPlugin))]
public class Plugin1 : IPlugin
{
private MainViewModel viewModel { get; set; }
public IPluginViewModel ViewModel
{
get { return viewModel; }
}
public ResourceDictionary View
{
get { return viewDictionary; }
}
private ResourceDictionary viewDictionary = new ResourceDictionary();
public string Title
{
get { return "Plugin 1"; }
}
[ImportingConstructor]
public Plugin1()
{
//I get the error here. tried both of these, none of them work
viewDictionary.Source =
// new Uri("pack://application:,,,/MefTest.Plugin1;component/views/main.xaml", UriKind.Absolute);
new Uri("/MefTest.Plugin1;component/views/main.xaml",
UriKind.Relative);
}
public override string ToString()
{
return Title;
}
}
然而,我收到错误Could not load file or assembly 'MefTest.Plugin1.dll, Culture=neutral' or one of its dependencies. The system cannot find the file specified.
Main.xaml
文件位于MefTest.Plugin1\Views\Main.xaml
文件夹中。项目的输出类型为ClassLibrary
,xaml文件的Build Action为Page
。
PS:我试图直接引用该插件并在没有MEF(Plugins.Add(new Plugin3.Plugin3());
)的情况下添加它,但它仍然抛出相同的异常。所以我认为问题不在于解决方案的MEF部分。
我该如何解决这个问题?此外,这种方法有更好的选择吗?
答案 0 :(得分:1)
我在xbap应用程序中这样做...来检索远程xaml。尝试对当地的信息做同样的事情
private ResourceDictionary LoadDictionary(string source)
{
Stream streamInfo = null;
ResourceDictionary dictionary = null;
try
{
streamInfo = DistantManager.Instance.GetResource(source);
if (streamInfo != null)
{
Uri baseUri = DistantManager.Instance.GetUri(source);
dictionary = XamlReader.Load(streamInfo) as ResourceDictionary;
dictionary.Source = baseUri;
}
}
catch (Exception e)
{
BusinessLogger.Manage(e);
return null;
}
return dictionary;
}
类似
Uri baseUri = new Uri(Mysource);
dictionary = XamlReader.Load(XXXX) as ResourceDictionary;
dictionary.Source = baseUri;
但另一方面我不明白为什么你想要一个ResourceDictionary作为你的插件视图......?只需创建插件用户控件??