2014-09-10 5 views
0

Я зарегистрировал экземпляр службы в Calibrurn's BootStrapper's Configure(), и он вводит правильно.Как обновить регистрацию Caliburn SimpleContainer IoC во время выполнения

public class AppBootstrapper : BootstrapperBase 
{ 
    private SimpleContainer _container; 

    // ... 
    // other overridden functions 
    // ... 

    protected override void Configure() 
    { 
     _container = new SimpleContainer(); 

     // ... 
     // window manager, event aggregator etc.. 
     // ... 

     if (_runInDemoMode) 
     { 
      // run in demo mode against a mock service 
      _container.Instance<IMyService>(new MyServiceMock()); 
     } 
     else 
     { 
      // run with the real service implementation 
      _container.Instance<IMyService>(new MyService()); 
     } 
    } 
} 

Я хотел бы иметь возможность обновить регистрацию правил зависимости от в ViewModel во время выполнения, так что пользователь может переключаться между реальной реализацией моей службы и макетом реализацией без необходимости перезапуска приложения.

E.g.

public class SettingsViewModel : PropertyChangedBase 
{ 
    // ... 
    // code 
    // ... 

    public void ChangeToDemoMode() 
    { 
     var container = IoC.GetContainer(); // <-- I made this up, how to do this? 
     container.UnregisterHandler(typeof(MyService), key?); // <-- I don't know what the key would be 
     container.Instance<IMyService>(new ServiceMock()); 
    } 
} 

Как вы можете видеть, что я не знаю, как получить ссылку на контейнер для того, чтобы возиться с ним, и я не знаю, как отменить существующую регистрацию после того как я сделать ссылку на контейнер , Есть ли способ сделать это или он будет разорвать ткань континуума IoC?

ответ

0

То, как я сделал это создать класс с зависимостью от SimpleContainer этого дает

public class CaliburnRegistrationService : IRegistrationService 
{ 
    SimpleContainer _container; 
    public CaliburnRegistrationService(SimpleContainer simpleContainer) 
    { 
     _container = simpleContainer; 
    } 

    public void Register(IResolver resolver) 
    { 
     // register you stuff based on interface implementation 
    } 
} 

Затем создайте реализации IResolver для каждого режима работы в вашем коде, например, DemoResolver и RealResolver

Затем в разделе Настройка загрузчика (в) сделать

_container.Singleton<IRegistrationService, CaliburnRegistrationService>(); 
_container.Singleton<IResolver, DemoResolver>(); // just some class that inherits from IResolver 
_container.Singleton<IResolver, RealResolver>(); // just some class that inherits from IResolver 

Побочный делая ViewModel зависит от IRegistrationService, это позволит вам позвонить Register из ViewModel.

И на основе некоторых параметров, которые вы можете зарегистрировать ваш контейнер

МОК
public class SettingsViewModel : PropertyChangedBase 
{ 
    IRegistrationService _registrationService; 
    IEnumerable<IResolver> _resolver; 
    public MyViewModel(IRegistrationService registrationService, IEnumerable<IResolver> resolver) 
    { 
     _registrationService = registrationService; 
     _resolver = resolver; 
    } 

    public void ChangeToMode() 
    { 
      foreach(var resl in _resolver) 
      { 
       if(resl.ShouldRegister(.. some parameter..)) 
       { 
        _registrationService.Register(resl); 
        return; 
       } 
      } 
    } 
} 

Это дает вам доступ к контейнеру IoC в любом месте