- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试在 WPF 应用程序中使用 Caliburn 和 MEF。我的 MEF 知识充其量只是粗略的。
这是 Bootstrap :
class Bootstrapper : BootstrapperBase
{
public Bootstrapper()
{
Initialize();
}
protected override void OnStartup(object sender, StartupEventArgs e)
{
DisplayRootViewFor<IShell>();
}
protected override void Configure()
{
//An aggregate catalog that combines multiple catalogs
var catalog = new AggregateCatalog();
//Adds all the parts found in the same assembly as the Program class
catalog.Catalogs.Add(new AssemblyCatalog(typeof(Bootstrapper).Assembly));
//Create the CompositionContainer with the parts in the catalog
container = new CompositionContainer(catalog);
var batch = new CompositionBatch();
batch.AddExportedValue<IWindowManager>(new WindowManager());
batch.AddExportedValue<IEventAggregator>(new EventAggregator());
batch.AddExportedValue(container);
container.Compose(batch);
}
protected override object GetInstance(Type serviceType, string key)
{
string contract = string.IsNullOrEmpty(key) ? AttributedModelServices.GetContractName(serviceType) : key;
var exports = container.GetExportedValues<object>(contract);
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 container.GetExportedValues<object>(AttributedModelServices.GetContractName(serviceType));
}
protected override void BuildUp(object instance)
{
container.SatisfyImportsOnce(instance);
}
这是 shellview:
<Window x:Class="MefCaliburn.ShellView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:MefCaliburn"
mc:Ignorable="d"
Title="ShellView" Height="300" Width="300">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="20"/>
<RowDefinition/>
<RowDefinition Height="100"/>
</Grid.RowDefinitions>
<ContentControl Grid.Row="0" x:Name="Menu"></ContentControl>
<ContentControl Grid.Row="1"></ContentControl>
<ContentControl Grid.Row="2" x:Name="Messages"></ContentControl>
</Grid>
IShell 接口(interface):
public interface IShell
{
}
这是我的 shell View 模型:
namespace MefCaliburn
{
[Export(typeof(IShell))]
public class ShellViewModel : PropertyChangedBase, IShell
{
private readonly IEventAggregator _events;
UserViewModel uvm;
[ImportingConstructor]
public ShellViewModel(MenuViewModel menu, MessagesViewModel mess, IEventAggregator eventaggregator)
{
Messages = mess;
Menu = menu;
_events = eventaggregator;
}
public MessagesViewModel Messages
{
get; set;
}
public MenuViewModel Menu
{
get; set;
}
public void LaunchUserViewModel()
{
uvm = new UserViewModel();
}
}
}
所以当Boostrapper重载方法时
protected override void OnStartup(object sender, StartupEventArgs e)
{
DisplayRootViewFor<IShell>();
}
被调用,我的 ShellViewModel 构造函数被调用,Menu 和 Messages View 模型被注入(inject)。这是一个依赖注入(inject)的例子,对吗?
在我的例子中,菜单和消息 View 模型是与 shell 一起创建的。但是如果一个新的 View 模型
[Export(typeof(UserViewModel))]
public class UserViewModel : PropertyChangedBase
{
private readonly IEventAggregator _events;
[ImportingConstructor]
public UserViewModel(IEventAggregator eventaggregator)
{
_events = eventaggregator;
}
}
当用户按下 MenuView.xaml 上的按钮时创建
<UserControl x:Class="MefCaliburn.MenuView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:MefCaliburn"
xmlns:cal="http://www.caliburnproject.org"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<StackPanel Orientation="Horizontal">
<Button Content="ONE" cal:Message.Attach="[Event Click] = [Action LaunchUserViewModel()]"></Button>
<Button Content="TWO"></Button>
</StackPanel>
</Grid>
此 UserViewModel 将向 MessagesViewModel 发布事件,我将需要 IEventAggregator。是的,我可以将它显式传递给构造函数,但我想了解的是为什么 MEF 不会注入(inject)它。
我是否尝试以非预期的方式使用 MEF? MEF 是否仅在应用程序启动时用于那些已知需要的 View 模型?
最佳答案
你有点糊涂了。首先,我认为你真的不想使用 MEF
首先,但我稍后会谈到。您尝试在 LaunchUserViewModel
中创建一个新的 View 模型. MEF
的整体思路|和 Dependency Injection
是摆脱它。正如你在这里看到的new UserViewModel()
当您尝试创建一个新实例时,您必须提供所有必需的参数。但整个想法是让框架完成工作并为我们提供它们。所以首先我们必须摆脱 new
关键字并考虑以不同的方式实例化它。让我们看看您的示例:
没关系。您导出某种类型的模块。
[Export(typeof(IUserViewModel))]
public class UserViewModel : PropertyChangedBase
{
private readonly IEventAggregator _events;
[ImportingConstructor]
public UserViewModel(IEventAggregator eventaggregator)
{
_events = eventaggregator;
}
}
public interface IUserViewModel {
void SomeMethod();
}
那么我们在导出东西的时候一般会怎么做呢?我们将其导入其他地方:
[Export(typeof(IShell))]
public class ShellViewModel : PropertyChangedBase, IShell
{
[Import]
public IUserViewModel Uvm { get; set; }
public void LaunchUserViewModel()
{
Uvm.SomeMethod(); // Your Uvm is already created
}
}
如您所见,我们已完成删除 new
关键词。这意味着 ShellViewModel
不知道它将导入什么类。这就是它的美妙之处。您可以随时交换实现,而不必更改 ShellViewModel
这里发生的是 AddExportedValue<IEventAggregator>(new EventAggregator());
通知MEF
,嘿,这是一个可能想要的类。稍后当你做 [ImportingConstructor]
, MEF
查找构造函数需要的类,如果有,它会为您注入(inject)它们。
现在,我想你只是想要 Dependency Injection
并进入了错误的框架。虽然MEF
允许您使用 DI
,它更强大。它使用模块的概念,以便您可以构建模块化应用程序。当您希望允许人们为您的应用程序编写插件时,它非常有用。
它看起来像:您只会向插件显示您希望它们显示的内容,因此您将创建一个名为 API
的项目。这将只存储契约(Contract)(接口(interface))。然后你会有你程序的Core
用户会提供 Plugins
.用户只会看到 API
, 不是 Core
,你会加载他们的插件,知道他们实际上实现了 API
您告诉他们要实现的接口(interface)。
你不需要MEF
使用 Dependency Injection
. Caliburn.Micro
已内置容器,但您也可以使用 Simple Injector , Ninject ,还有更多。
我希望这是有道理的。这是一个庞大的主题。
编辑:
我创建了一个非常基本的 project 使用Caliburn.Micro
依赖注入(inject)。也许它会帮助您更好地理解它。
关于c# - WPF Caliburn MEF 应用程序和 DI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44784746/
我刚刚用 java-swing 为我写了一个桌面时钟,我希望每次登录时该时钟都运行。 为此,我将我的 jar 文件添加到 start 文件夹,我让时钟开始运行。 但我的问题是 - 任务栏中显示的图标允
我正在尝试编写一个程序来检查用户是否上传了新视频。我想让它成为一项后端工作,不断检查用户最近的视频,然后使用我的应用程序向我的用户发送推送。有关于这个问题的任何文档或示例代码吗?我完全不知道从哪里开始
我正在为我的 Raspberry Pi 编写一个程序,该程序由两个主要部分组成: 使用 Spotify-API“Libspotify”搜索音乐并播放音乐的 C 程序。 一个在 apache2 We
我做了一个C++生成命令行并将命令转发给它的程序。目前,我正在将 cmd 控制台的输出发送到一个文件,并在我的 C++ 程序中读取它。但我想让它与管道一起工作。 是否可以从 Windows cmd 行
是否可以使用 C 程序和 malloc 找出处理器的页面大小?而不是使用 sysconf() 调用? 最佳答案 如果你可以#include一些linux内核头文件,你可以在中找到宏PAGE_SIZE
关闭。这个问题需要多问focused 。目前不接受答案。 想要改进此问题吗?更新问题,使其仅关注一个问题 editing this post . 已关闭 8 年前。 Improve this ques
我想实现一个算法: 从 Ruby on Rails 应用程序获取数据库对象作为输入, 对输入执行计算, 根据计算查询 Rails 数据库, 并根据查询生成一组有序结果。 我将用 C(也许是 Objec
我今天的任务是创建一个 Python 脚本(例如 A.py),它可以执行以下操作: 启动 C 程序(例如 CProg)并传递一些参数 启动另一个 Python 脚本(例如 B.py)并传递其他参数 加
我有一个在后台运行的 .NET 程序,需要创建一个可以与该程序通信的 Windows Shell 扩展。起初我以为我会在 .NET 中创建我的 Shell Extension,并使用 IpcServe
Python 程序做前端工作,C 程序做后端工作。它们中的每一个都是一个单独的过程。 Python 进程充当主进程,向 C 进程发送信号和事件。 C 进程生成统计信息、计数器和信息,这些信息被发送回
如何与 shell 脚本共享 C 头文件? shell 脚本通过命名管道与 C 程序通信。让我们假设 C 头文件中定义的枚举 SAMPLE_ONE 由 C 程序写入管道。 shell 脚本从管道中读出
我有一些客户/候选人提示我的程序不能在他们的 Windows 7 64 位版本上运行(已通过屏幕截图确认)。错误很奇怪,例如: in the trial version i am getting a
这个问题在这里已经有了答案: Why SDL defines main macro? (2 个答案) 关闭 7 年前。 我在 Windows 操作系统下使用 QT Creator 的简单程序中使用
我的导师给了我们一个基本的 C shell 来扩展,我目前正在努力让 shell 在用户在命令行中输入“cd [directory]”时更改目录。我已经得到它来停止段错误,但它不会更改目录。谁能告诉我
我以前有过这个工作,但我使用的是指针。 getenv() 不断崩溃,所以我使用 sprintf() 复制了结果。现在我想用 : 删除并只打印第一次出现的地方。请帮忙! #include #inclu
你好,我第一次使用 C primer plus book 学习 C,然后在第 16 章关于 C11 标准的 _Generic 我在 Eclipse c/c++ 中编写了一个程序并构建它产生了 8 个错
我正在尝试从另一个 C 程序执行 python 程序,其中 py 脚本的返回值为 int array[3] 我可以从 python 退出代码中获取这个数组吗?? 编辑:如果问题不清楚,我可以将 pyt
// The countChicken() method should count the number of occurrences of the word chicken (or some oth
我已经通过 ZMQ 使用同一类成功地从 C# 和 C++ 程序传输数据,其中 C++ 类是数据定义,编译器幸运地将字节数组屏蔽到类。 我如何在 C# 和 Node.js 程序之间做同样的事情?我认为他
任何人都可以为我指明有关 makefile 如何工作以及如何使用 eclipse 从头开始基本程序的好教程的方向吗?我正在为 fedora 和 C++ 使用 eclipse 3.4.1 版。提前致
我是一名优秀的程序员,十分优秀!