为了使用MEF2的PCL版本,我不确定如何连接Caliburn.Micro。我见过MefBootstrapper example,但它使用了许多不可用的类,我在转换到新的API时遇到了麻烦。
这是我到目前为止所知道的:
using System;
using System.Collections.Generic;
using System.Composition;
using System.Composition.Hosting;
using System.Linq;
using Caliburn.Micro;
namespace Test
{
public class Bootstrapper : BootstrapperBase
{
private CompositionHost _host;
public Bootstrapper()
{
Initialize();
}
protected override void Configure()
{
var config = new ContainerConfiguration();
config.WithAssemblies(AssemblySource.Instance);
// batch.AddExportedValue<IWindowManager>(new WindowManager());
// batch.AddExportedValue<IEventAggregator>(new EventAggregator());
// batch.AddExportedValue(container);
_host = config.CreateContainer();
}
protected override object GetInstance(Type serviceType, string key)
{
string contract = string.IsNullOrEmpty(key) ? serviceType.ToString() : key;
var exports = _host.GetExports<object>(contract).ToArray();
if (exports.Any())
return exports.First();
throw new Exception(string.Format("Could not locate any instances of contract {0}.", contract));
}
protected override IEnumerable<object> GetAllInstances(Type serviceType)
{
return _host.GetExports<object>(serviceType.ToString());
}
protected override void BuildUp(object instance)
{
_host.SatisfyImports(instance);
}
protected override void OnStartup(object sender, System.Windows.StartupEventArgs e)
{
DisplayRootViewFor<IShell>();
}
}
}但是,CompositionHost似乎没有任何导出,我也不知道如何向其中添加对象(WindowManager和EventAggregator)。
发布于 2015-07-11 05:09:43
在尝试了一下之后,下面是我想出的方法,它似乎起作用了:
[Export(typeof(IWindowManager))]
public class MyWindowManager : WindowManager
{
}
[Export(typeof(IEventAggregator))]
public class MyEventAggregator : EventAggregator
{
}
public interface IShell
{
}
public class AppBootstrapper : BootstrapperBase
{
private CompositionHost _host;
public AppBootstrapper()
{
Initialize();
}
protected override IEnumerable<Assembly> SelectAssemblies()
{
// TODO: Add additional assemblies here
yield return typeof(AppBootstrapper).GetTypeInfo().Assembly;
}
protected override void Configure()
{
var config = new ContainerConfiguration();
var assemblies = AssemblySource.Instance.Union(SelectAssemblies());
config.WithAssemblies(assemblies);
_host = config.CreateContainer();
}
protected override object GetInstance(Type serviceType, string key)
{
var exports = _host.GetExports(serviceType, key).ToArray();
if (exports.Any())
return exports.First();
throw new Exception(string.Format("Could not locate any instances of contract {0}.", serviceType.Name));
}
protected override IEnumerable<object> GetAllInstances(Type serviceType)
{
return _host.GetExports<object>(serviceType.ToString());
}
protected override void BuildUp(object instance)
{
_host.SatisfyImports(instance);
}
protected override void OnStartup(object sender, System.Windows.StartupEventArgs e)
{
DisplayRootViewFor<IShell>();
}
}发布于 2015-12-15 02:09:30
我的回复肯定是晚了,但也许这对其他正在为可怜的MEF2文档而苦苦挣扎的人有帮助,当然它也可能对我有帮助,如果有人想出更好的实现,或者在这个解决方案中发现任何问题;所以就是这样。
对于面向属性较少的方法(这是基本的MEF2特性之一),为了避免将CM注入包包装到自定义类中的麻烦,您必须配置程序集导出,如下所示:
protected override IEnumerable<Assembly> SelectAssemblies()
{
return new[]
{
typeof (IEventAggregator).GetTypeInfo().Assembly,
typeof (IWindowManager).GetTypeInfo().Assembly,
typeof (MefBootstrapper).GetTypeInfo().Assembly
};
}
protected override void Configure()
{
var config = new ContainerConfiguration();
// note that the event aggregator is in the core CM assembly,
// while the window manager in the platform-dependent CM assembly,
// so that we need 2 conventions for 2 assemblies.
ConventionBuilder cmBuilder = new ConventionBuilder();
cmBuilder.ForType<EventAggregator>().Export<IEventAggregator>();
ConventionBuilder cmpBuilder = new ConventionBuilder();
cmpBuilder.ForType<WindowManager>().Export<IWindowManager>();
ConventionBuilder appBuilder = new ConventionBuilder();
appBuilder.ForTypesMatching(t =>
t.Name.EndsWith("ViewModel", StringComparison.OrdinalIgnoreCase)).Export();
appBuilder.ForType<MainViewModel>().Export<IShell>();
config.WithAssembly(typeof(IEventAggregator).GetTypeInfo().Assembly, cmBuilder);
config.WithAssembly(typeof(IWindowManager).GetTypeInfo().Assembly, cmpBuilder);
config.WithAssembly(typeof(MefBootstrapper).GetTypeInfo().Assembly, appBuilder);
_host = config.CreateContainer();
}从本质上讲,你必须注意几件事:
Caliburn.Micro.Platform中。EventAggregator标记为exports,作为要为接口IEventAggregator选择的实现,对于窗口管理器也是如此;此外,我将主视图模型作为IShell接口的实现导出,并通过从我的应用程序集中导出名称以ViewModel结尾的所有类来导出所有视图模型。这样,我就不需要任何ExportAttribute.了
https://stackoverflow.com/questions/29523482
复制相似问题