我們使用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); }