问题
I have a class MyResource
in my application that looks like this:
public class MyResource : IMyResource
{
// ... whatever ...
}
And when I initialize my application in App.xaml.cs I have something like that using Autofac:
builder.Register<IMyResource>(container => new MyResource());
Now I need to add a StaticResource
in a Window
of my WPF application, something like this:
<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. Moreover, I may need to use an instance of MyResource
in different Window
s or UserControl
s across my application. So I would like to use an instance of MyResource
as a StaticResource
for my Window
that is resolved through the Autofac container. 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.
I was also thinking of doing something like that in App.xaml.cs, when I initialize the application:
App.Current.MainWindow.Resources.Add("MyResource", container.Resolve<IMyResource>());
But when I use the resource in my 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. 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?
回答1:
Follow these steps
- Register
MyWindow
andMyResource
with Autofac. - Place
IMyResource
in the constructor ofMyWindow
(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 theDataContext
somewhere) - Set
DataContext
to your concrete instance ofIMyResource
(in the constructor), or if you are using MVVM, place the instance into your viewmodel (which would also be registered with Autofac). - Resolve
MyWindow
In code:
MyWindow(IMyResource myResource) : this()
{
DataContext = myResource;
}
If you are using a ViewModel (also registered with Autofac):
MyWindow(MyViewModel viewModel) : this()
{
DataContext = viewModel;
}
Add this line to your XAML:
<Window.DataContext><local:IMyResource></Window.DataContext>
Or this:
<Window.DataContext><local:MyViewModel></Window.DataContext>
And then your markup for ListBox
becomes trivial:
<ListBox ItemsSource="{Binding}"/>
Or, with the viewmodel, as the property Items
, for instance, it's just as nice:
<ListBox ItemsSource="{Binding Items}"/>
来源:https://stackoverflow.com/questions/10469308/resolving-dependencies-in-xaml-using-autofac