MVVM フレームワークには Caliburn.Micro、IoC コンテナーには StructureMap、メディエーターの実装には MediatR を使用しています。MediatR イベント ハンドラーを登録するための推奨される方法が、ViewModels を独自のハンドラーとして使用する Caliburn.Micro の推奨されるアプローチとうまく機能しないことを除いて、これはすべて正常に機能します。
Caliburn.Micro は、EventAggregator を介してメディエーター パターンを実装します。これには、ViewModel に IEventAggregator を挿入し、それ自体にサブスクライブする (または IHandle<> インターフェイスを実装する何か) 必要があります。MediatR はより分離されたアプローチを採用しており、IRequestHandler<,> およびその他の型を閉じる型のアセンブリを反射的にスキャンすることをお勧めします。
私の問題は、StructureMap の経験不足だと思います。
私がやりたいのは、ViewModels 自体に Handler 機能を実装できるようにすることです (Caliburn.Micro が示唆するように) だけでなく、ViewModels が Caliburn.Micro のシングルトンとして登録されるようにすることもできます。
public class RibbonMenuViewModel : PropertyChangedBase, INotificationHandler<SomethingSelectedEvent> { }
StructureMap が次のレジストリを処理する場合、RibbonMenuViewModel の 2 つのインスタンスがあります。1 つは Caliburn.Micro のシングルトン バージョンで、もう 1 つは 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<>));
});
}
}
MediatR の INotificationHandler インスタンスとして Singleton ViewModel 登録を使用する最善の方法についてアドバイスをお願いします
参照用の 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); }