ViewModels作为处理程序与MediatR,StructureMap,Caliburn.Micro
问题描述:
我们使用Caliburn.Micro作为MVVM框架,StructureMap作为我们的IoC容器,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); }
答
我有类似的问题。 这是我如何修复它。
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));
}
}
我希望这有助于。