使用Autofac解决XAML中的依赖关系

时间:2012-05-06 08:50:16

标签: c# wpf xaml dependency-injection autofac

我的应用程序中有一个类MyResource,如下所示:

public class MyResource : IMyResource
{
    // ... whatever ...
}

当我在App.xaml.cs中初始化我的应用程序时,我有类似的东西使用Autofac:

builder.Register<IMyResource>(container => new MyResource());

现在我需要在我的WPF应用程序的StaticResource中添加Window,如下所示:

<Window.Resources>
    <local:MyResource x:Key="MyResource" />
</Window.Resources>

但是,当然,整个想法是在这里引用MyResource的具体实例。此外,我可能需要在我的应用程序中的不同MyResourceWindow中使用UserControl的实例。所以我想使用MyResource的{​​{1}}实例作为StaticResource通过Autofac容器解析的Window。我怎样才能做到这一点?

我正在考虑在Window的代码隐藏中添加资源,但它可能会创建一个我不想要的容器依赖。

当我初始化应用程序时,我还想在App.xaml.cs中做类似的事情:

App.Current.MainWindow.Resources.Add("MyResource", container.Resolve<IMyResource>());

但是当我在XAML中使用资源时

<ListBox ItemsSource="{Binding Source={StaticResource ResourceKey=MyResource}}"/>

我得到一个XAMLParseException内部异常的消息,指出无法找到名为MyResource的资源。即使它正常工作,我觉得它有点臭。

那怎么能实现呢?它只有可能吗?如果不是,实现这个的最佳方式是什么?

1 个答案:

答案 0 :(得分:1)

请按照以下步骤操作

  • 使用Autofac注册MyWindowMyResource
  • IMyResource放在MyWindow的构造函数中(是的,您正在修改后面的代码,但您并不是指您的容器。如果您无法在代码隐藏中使用代码 - 也许你是一个UserControl - 然后确保有人在某处设置DataContext
  • DataContext设置为IMyResource的具体实例(在构造函数中),或者如果您使用的是MVVM,请将实例放入您的viewmodel(也可以使用Autofac注册)。
  • 解析MyWindow

在代码中:

MyWindow(IMyResource myResource) : this()
{
  DataContext = myResource;
}

如果您使用的是ViewModel(也在Autofac中注册):

MyWindow(MyViewModel viewModel) : this()
{
  DataContext = viewModel;
}

将此行添加到您的XAML:

<Window.DataContext><local:IMyResource></Window.DataContext>

或者这个:

<Window.DataContext><local:MyViewModel></Window.DataContext>

然后你的ListBox标记变得微不足道了:

<ListBox ItemsSource="{Binding}"/>

或者,使用viewmodel,作为属性Items,例如,它同样很好:

<ListBox ItemsSource="{Binding Items}"/>