我们使用Caliburn.Micro作为我们的MVVM框架,使用StructureMap作为IoC容器,使用MediatR作为我们的中介实现。这一切都很好,除了注册MediatR事件处理程序的推荐方法与Caliburn.Micro推荐的方法并没有很好地结合使用ViewModels作为他们自己的处理程序。
Caliburn.Micro通过EventAggregator实现中介模式,这需要您将IEventAggregator注入ViewModel并订阅自身(或实现IHandle<>接口的东西)。 MediatR采用更加分离的方法,建议您反射扫描程序集以查找关闭IRequestHandler<,>的类型。和其他类型。
我相信我缺乏结构化的经验,这是我的问题。
我想要做的是能够在ViewModel上实现Handler功能(如Caliburn.Micro建议),但也要确保ViewModel注册为Caliburn.Micro的Singletons。
public class RibbonMenuViewModel : PropertyChangedBase, INotificationHandler<SomethingSelectedEvent> { }
当StructureMap处理以下注册表时,将有2个RibbonMenuViewModel实例:一个用于Caliburn.Micro的单例版本和一个关闭MediatR INotificationHandler&lt;&gt;的瞬态版本。通用类型。
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 ViewModel注册作为MediatR的INotificationHandler实例的最佳方法提出建议
以下是Caliburn.Micro配置供参考:
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 :(得分: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));
}
}
我希望这会有所帮助。