令我惊讶的是,每个IoC/MVVM教程都没有涵盖此问题,因此希望我能忽略一些明显的问题。

简而言之,我的问题是:如何将Autofac LifeTimeScope与ViewModel的生命周期相关联。

考虑下面的简单应用程序。

-------------------------------------------------
|                                          _ o x |
-------------------------------------------------
|          |                                     |
| Item A   |                                     |
| Item B   |       DetailView for Item A         |
| Item C   |                                     |
|          |                                     |
|------------------------------------------------

该应用程序包含五个 View :
  • MainView
  • ListView
  • ADetailView
  • BDetailView
  • CDetailView

  • 以及五个 View 模型
  • MainViewModel
  • ListViewModel
  • ADetalViewModel
  • BDetalViewModel
  • CDetalViewModel

  • 主 View 的结构如下。
    <Grid Margin="5">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="1*"></ColumnDefinition>
            <ColumnDefinition Width="5"></ColumnDefinition>
            <ColumnDefinition Width="2*"></ColumnDefinition>
        </Grid.ColumnDefinitions>
    
        <ListView Grid.Column="0">
        </ListView>
    
        <GridSplitter Grid.Column="1"/>
    
        <Border Grid.Column="2">
            <Border.Resources>
                <DataTemplate DataType="{x:Type vm:ADetailViewModel}">
                    <vw:ADetailView></vw:ADetailView>
                </DataTemplate>
                <DataTemplate DataType="{x:Type vm:BDetailViewModel}">
                    <vw:BDetailView></vw:BDetailView>
                </DataTemplate>
                <DataTemplate DataType="{x:Type vm:CDetailViewModel}">
                    <vw:CDetailView></vw:CDetailView>
                </DataTemplate>
            </Border.Resources>
            <ContentPresenter Content="{Binding CurrentDetailViewModel}"></ContentPresenter>
        </Border>
    
    </Grid>
    

    因此,它是模板驱动器用户界面,其中模板类型将触发对正确 View 的更改。为此,我们必须实例化正确类型的ViewModel并将其分配给MainViewModel中的CurrentDetailViewModel。

    现在我提出了问题。我非常喜欢创建此详细信息 View 模型,以触发LifetimeScope的创建。然后,它的所有依赖关系都将驻留在此范围内,并且在切换到另一个 View / View 模型时可以轻松地将其丢弃。

    对于Autofac,这必须是一个非常非常常见的用例,我很好奇其他人如何使用它。

    最佳答案

    我会将当前的方法添加到答案列表中,希望有人会添加或给出更好的答案。

    我利用了拥有的。当容器找到声明为Owned<>的内容时,它将在其自己的新生命周期范围内创建实例。然后,(默认情况下)所有依赖项也将最终落入此生存期范围。但是,必须通过调用Dispose()手动销毁lifelifescope。在下面的示例中,我将Owned与Func结合使用,获得了用于创建任意数量的拥有实例的工厂。

    构造函数:

    private readonly Func<Owned<ADetailViewModel> _aFactory;
    private readonly Func<Owned<BDetailViewModel> _bFactory;
    private readonly Func<Owned<CDetailViewModel> _cFactory;
    
    private IDisposable _currentOwned;
    
    public MainViewModel(Func<int, Owned<ADetailViewModel>> aFactory,
                         Func<int, Owned<BDetailViewModel>> bFactory,
                         Func<int, Owned<CDetailViewModel>> cFactory)
    {
        _aFactory= aFactory;
        _bFactory= bFactory;
        _cFactory= cFactory;
    }
    

    SwitchDetailViewCommand:
    private RelayCommand<IListItemViewModel> _switchDetailViewCommand ;
    public RelayCommand<IListItemViewModel> SwitchDetailViewCommand
    {
        get
        {
            return _switchDetailViewCommand ?? (_switchDetailViewCommand = new RelayCommand<IListItemViewModel>(
                (listitem) =>
                {
                    if (_currentOwned != null)
                    {
                        _currentOwned.Dispose();
                    }
                    switch (listitem.Type)
                    {
                        case "A":
                        {
                            var aOwned = _aFactory();
                            _currentOwned = aOwned;
                            CurrentDetailViewModel = _aOwned.Value;
                            break;
                        }
                        case "B":
                        {
                            var bOwned = _bFactory();
                            _currentOwned = bOwned;
                            CurrentDetailViewModel = _bOwned.Value;
                            break;
                        }
                        case "C":
                        {
                            var cOwned = _cFactory();
                            _currentOwned = cOwned;
                            CurrentDetailViewModel = _cOwned.Value;
                            break;
                        }
                        default:
                        {
                            break;
                        }
                    }
                }
            ));
        }
    }
    

    关于wpf - Autofac:将LifeTimeScope与MVVM中ViewModel的生存期相关,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37549461/

    10-10 17:51