简体   繁体   English

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

[英]Resolving dependencies in XAML using Autofac

I have a class MyResource in my application that looks like this: 我的应用程序中有一个MyResource类,如下所示:

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

And when I initialize my application in App.xaml.cs I have something like that using Autofac: 当我在App.xaml.cs中初始化应用程序时,使用Autofac会得到类似的结果:

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

Now I need to add a StaticResource in a Window of my WPF application, something like this: 现在,我需要在WPF应用程序的Window中添加一个StaticResource ,如下所示:

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

But of course, the whole idea is not to reference a concrete instance of MyResource here. 但是,当然,整个想法不是在这里引用MyResource的具体实例。 Moreover, I may need to use an instance of MyResource in different Window s or UserControl s across my application. 此外,我可能需要在应用程序的不同WindowUserControl使用MyResource的实例。 So I would like to use an instance of MyResource as a StaticResource for my Window that is resolved through the Autofac container. 因此,我想将MyResource的实例用作通过Autofac容器解析的WindowStaticResource How can I achieve this? 我该如何实现?

I was thinking of adding the resource in the code-behind of my Window , but it may create a dependency on my container which I don't want. 我当时正在考虑在Window的代码后面添加资源,但是这可能会导致我不需要的容器依赖项。

I was also thinking of doing something like that in App.xaml.cs, when I initialize the application: 初始化应用程序时,我还考虑在App.xaml.cs中执行类似的操作:

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

But when I use the resource in my XAML 但是当我在XAML中使用资源时

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

I get an XAMLParseException which inner exception's message stating that the resource named MyResource cannot be found. 我收到一个XAMLParseException ,它XAMLParseException内部异常消息,指出找不到名为MyResource的资源。 And even if it was working, I feel like it's a bit smelly. 即使工作正常,我仍感觉有点臭。

So how can this be achieved? 那么如何实现呢? Is it only possible? 有可能吗? If not what are the best way to implement this? 如果不是,最好的方法是什么?

Follow these steps 跟着这些步骤

  • Register MyWindow and MyResource with Autofac. 向Autofac注册MyWindowMyResource
  • Place IMyResource in the constructor of MyWindow (Yes, you are modifying the code behind, but you are not referring to your container. If you cannot have code in the Code-behind -- perhaps you are a UserControl --then make sure someone is setting the DataContext somewhere) IMyResource放置在MyWindow的构造函数中(是的,您正在修改后面的代码,但是您不是在引用容器。如果您无法在代码隐藏代码中使用代码-也许您是UserControl-那么请确保有人在在某处设置DataContext
  • Set DataContext to your concrete instance of IMyResource (in the constructor), or if you are using MVVM, place the instance into your viewmodel (which would also be registered with Autofac). DataContext设置为IMyResource的具体实例(在构造函数中),或者如果您使用的是MVVM,则将该实例放入您的视图模型(也将在Autofac中注册)。
  • Resolve MyWindow 解决MyWindow

In code: 在代码中:

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

If you are using a ViewModel (also registered with Autofac): 如果您使用的是ViewModel(也已在Autofac中注册):

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

Add this line to your XAML: 将此行添加到您的XAML:

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

Or this: 或这个:

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

And then your markup for ListBox becomes trivial: 然后,您对ListBox的标记变得微不足道:

<ListBox ItemsSource="{Binding}"/>

Or, with the viewmodel, as the property Items , for instance, it's just as nice: 或者,使用viewmodel作为属性Items ,例如:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM