2016-03-02 88 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)); 

    } 
} 

我希望这有助于。