2014-02-03 2 views
1

Мы используем Caliburn Micro в первый раз. У нас есть AppBootstrapper, унаследованный от ShellViewModel. Ситуация заключается в том, что VieModels должен иметь один и тот же экземпляр, если он не сбрасывается.Экземпляр в Caliburn Micro

Мы можем достичь общего или общего доступа каждый раз, но выпуск экспорта в случае необходимости по-прежнему остается загадкой.

public class AppBootstrapper : Bootstrapper<ShellViewModel> 
{ 
    private static CompositionContainer _container; 

    protected override void Configure() 
    { 
     try 
     { 
      _container = new CompositionContainer(
       new AggregateCatalog(AssemblySource.Instance.Select(x => new AssemblyCatalog(x)))); 

      var batch = new CompositionBatch(); 

      batch.AddExportedValue<IWindowManager>(new WindowManager()); 
      batch.AddExportedValue<IEventAggregator>(new EventAggregator()); 
      batch.AddExportedValue(_container); 

      StyleManager.ApplicationTheme = ThemeManager.FromName("Summer"); 

      _container.Compose(batch); 
     } 
     catch (Exception exception) 
     { 
     } 
    } 

    public static void ReleaseAll() 
    { 

    } 

    protected override object GetInstance(Type serviceType, string key) 
    { 
     try 
     { 
      var 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)); 
     } 
     catch (ReflectionTypeLoadException ex) 
     { 
      foreach (Exception inner in ex.LoaderExceptions) 
      { 
       // write details of "inner", in particular inner.Message 
      } 
      return null; 
     } 
    } 

    protected override IEnumerable<object> GetAllInstances(Type serviceType) 
    { 
     try 
     { 
      return _container.GetExportedValues<object>(AttributedModelServices.GetContractName(serviceType)); 
     } 
     catch (Exception exception) 
     { 
      return null; 
     } 
    } 

    protected override void BuildUp(object instance) 
    { 
     _container.SatisfyImportsOnce(instance); 
    } 
} 

ShellViewModel

[Export(typeof(ShellViewModel))] 
public sealed class ShellViewModel : Conductor<IScreen>.Collection.OneActive, IHandle<object> 
{ 
    [ImportingConstructor] 
    public ShellViewModel(CompositionContainer compositionContainer, IEventAggregator eventAggregator) 
    { 
     CompositionContainer = compositionContainer; 
     EventAggregator = eventAggregator; 
     eventAggregator.Subscribe(this); 

     Items.Add(compositionContainer.GetExportedValue<AViewModel>()); 
     Items.Add(compositionContainer.GetExportedValue<BViewModel>()); 

     ActivateItem(Items.Single(p => p.DisplayName == AppMessageType.A.ToString())); 
    } 

    public IEventAggregator EventAggregator { get; set; } 
    public CompositionContainer CompositionContainer { get; set; } 

    public void Handle(object message) 
    { 
     //throw new System.NotImplementedException(); 
    } 

    public void B() 
    { 
     ActivateItem(Items.Single(p => p.DisplayName == AppMessageType.B.ToString())); 
    } 

    public void A() 
    { 
     ActivateItem(Items.Single(p => p.DisplayName == AppMessageType.A.ToString())); 
    } 

    public void RESET() 
    { 
     AppBootstrapper.ReleaseAll(); 
     ActivateItem(Items.Single(p => p.DisplayName == AppMessageType.A.ToString())); 
    } 

    public enum AppMessageType 
    { 
     A, 
     B 
    } 
} 

AViewModel

[Export(typeof(AViewModel))] 
public sealed class AViewModel : Conductor<IScreen>.Collection.OneActive, IHandle<object> 
{ 
    [ImportingConstructor] 
    public AViewModel(CompositionContainer compositionContainer, IEventAggregator eventAggregator) 
    { 
     DisplayName = ShellViewModel.AppMessageType.A.ToString(); 

     CompositionContainer = compositionContainer; 
     EventAggregator = eventAggregator; 
     eventAggregator.Subscribe(this); 
    } 

    public IEventAggregator EventAggregator { get; set; } 
    public CompositionContainer CompositionContainer { get; set; } 


    public void Handle(object message) 
    { 
     //throw new System.NotImplementedException(); 
    } 
} 

BViewModel

[Export(typeof(BViewModel))] 
public sealed class BViewModel : Conductor<IScreen>.Collection.OneActive, IHandle<object> 
{ 
    [ImportingConstructor] 
    public BViewModel(CompositionContainer compositionContainer, IEventAggregator eventAggregator) 
    { 
     DisplayName = ShellViewModel.AppMessageType.B.ToString(); 

     CompositionContainer = compositionContainer; 
     EventAggregator = eventAggregator; 
     eventAggregator.Subscribe(this); 
    } 

    public IEventAggregator EventAggregator { get; set; } 
    public CompositionContainer CompositionContainer { get; set; } 


    public void Handle(object message) 
    { 
     //throw new System.NotImplementedException(); 
    } 
} 

Теперь AViewModel и BViewModel имеют один экземпляр. Когда нажата кнопка Release, я хочу иметь новый экземпляр AViewModel и BViewModel.

В надежде, скоро ответит.

С уважением, Вивек

ответ

2

При работе с контейнером IoC, только часть вашего кода, который должен принять его как зависимость должна быть вашим composition root (т.е. ваш AppBootstrapper в данном случае). Вы не должны вводить или ссылаться на контейнер в другом месте вашего кода (кроме, возможно, заводов).

Если вы хотите, чтобы ваш ShellViewModel контролировать срок службы ваших моделей зрения детей (A и B), то вам следует рассмотреть вливание вида модель фабрики в свой ShellViewModel (через конструктор инъекцию, если они необходимы зависимость).

Ваш AViewModelFactory просто иметь один Create метод, который возвращает новый экземпляр AViewModel, также с BViewModelFactory. Вы можете просто обновить свои модели просмотра непосредственно на заводах. Если ваши модели просмотра имеют большие сети зависимостей, то вы можете подумать о добавлении ссылки на свой контейнер на фабриках, хотя желательно рассмотреть возможность поиска в MEF ExportFactory<T>.

Смежные вопросы