2016-03-02 87 views
2

我們使用Caliburn.Micro作爲MVVM框架,StructureMap作爲我們的Io​​C容器,MediatR作爲我們的中介器實現。這一切都工作正常,除了推薦的方式註冊MediatR事件處理程序不能很好地與Caliburn.Micro推薦的方法使用ViewModels作爲自己的處理程序。ViewModels作爲處理程序與MediatR,StructureMap,Caliburn.Micro

Caliburn.Micro通過EventAggregator實現中介模式,該模式要求您將IEventAggregator注入ViewModel並訂閱自己(或者實現IHandle接口)。 MediatR採用了更加分離的方法,建議您反射性地掃描程序集以查找關閉IRequestHandler和其他類型的類型。

我相信這是我對StructureMap的缺乏經驗,這是我的問題。

我想要做的就是能夠在ViewModels本身上實現處理程序功能(如Caliburn.Micro建議),但也要確保ViewModel註冊爲Caliburn.Micro的Singletons。

public class RibbonMenuViewModel : PropertyChangedBase, INotificationHandler<SomethingSelectedEvent> { } 

當StructureMap處理以下注冊表,會有RibbonMenuViewModel的2個實例:一個單版本Caliburn.Micro和關閉所述MediatR INotificationHandler <>通用類型一個瞬態版本。

StructureMap登記

public class ViewModelsRegistry : Registry 
    { 
     public ViewModelsRegistry() 
     { 

      // ensure registration for the ViewModel for Caliburn.Micro 
      this.ForConcreteType<RibbonMenuViewModel>().Configure.Singleton(); 


      // MediatR handler registrations 
      this.Scan(s => 
      { 
       s.Assembly(this.GetType().Assembly); 

       s.ConnectImplementationsToTypesClosing(typeof (IRequestHandler<,>)); 
       s.ConnectImplementationsToTypesClosing(typeof (IAsyncRequestHandler<,>)); 
       s.ConnectImplementationsToTypesClosing(typeof (INotificationHandler<>)); 
       s.ConnectImplementationsToTypesClosing(typeof (IAsyncNotificationHandler<>)); 
      }); 

     } 
    } 

我想上使用Singleton視圖模型註冊爲INotificationHandler實例MediatR

這裏最好的辦法是建議,以供參考Caliburn.Micro配置:

Caliburn引導程序配置

protected override void Configure() 
    { 
     this.configureTypeMappings(); 

     if (!Execute.InDesignMode) 
     { 
      this.configureIocContainer(); 
     } 
    } 

    private void configureIocContainer() 
    { 
     this.container = new Container(this.getStructureMapConfig); 
    } 


    private void getStructureMapConfig(ConfigurationExpression cfg) 
    { 
     cfg.For<IWindowManager>().Use<WindowManager>().Singleton(); 

     cfg.Scan(s => 
     { 
      s.AssemblyContainingType<ViewModelsRegistry>(); 

      s.LookForRegistries(); 
     }); 
    } 


    protected override IEnumerable<object> GetAllInstances(Type serviceType) 
    { 
     return this.container.GetAllInstances(serviceType).OfType<object>(); 
    } 


    protected override object GetInstance(Type serviceType, string key) 
    { 
     if (serviceType == null) serviceType = typeof(object); 
     var returnValue = key == null 
       ? this.container.GetInstance(serviceType) : this.container.GetInstance(serviceType, key); 
     return returnValue; 
    } 
    protected override void BuildUp(object instance) { this.container.BuildUp(instance); } 

回答

0

我有類似的問題。 這是我如何修復它。

public class ViewModelsRegistry : Registry 
{ 
    public ViewModelsRegistry() 
    { 

     // MediatR handler registrations 
     this.Scan(s => 
     { 
      s.Assembly(this.GetType().Assembly); 

      s.ConnectImplementationsToTypesClosing(typeof (IRequestHandler<,>)); 
      s.ConnectImplementationsToTypesClosing(typeof (IAsyncRequestHandler<,>)); 
      s.ConnectImplementationsToTypesClosing(typeof (INotificationHandler<>)); 
      s.ConnectImplementationsToTypesClosing(typeof (IAsyncNotificationHandler<>)); 
      s.ExcludeType<RibbonMenuViewModel>(); 
     }); 
     // ensure registration for the ViewModel for Caliburn.Micro   

     For(typeof(INotificationHandler<>)).Singleton().Add(typeof(RibbonMenuViewModel)); 

    } 
} 

我希望這有助於。