通过 Bootstrapper OnStartUp 将 Repository 注入 ShellViewModel
Injection of Repository into ShellViewModel, via Bootstrapper OnStartUp
我卡住了!
我正在使用 Caliburn.micro
来消除在 WPF
应用程序中实施 MVVM
的一些痛苦。
目前我只有一个 View / ViewModel,但将来可能会有多个 ViewModel。当前的 ViewModel 正在使用存储库来填充对象列表:
public class ShellViewModel : Screen
{
private IMyObjectRepository<IMyObject> _myObjectsRepo = null;
private BindableCollection<MyObject> _myObjects;
private string _connString;
/// <summary>
/// constructor
/// </summary>
public ShellViewModel()
{
//call the method which sets up the repository
GetMyObjectsRepository();
//following three lines cast the list from type IReport to type Report
var IMyObjects= _myObjectsRepo.GetAllIMyObjects();
var myObjects = IMyObjects.OfType<MyObject>().ToList();
MyObjects = new BindableCollection<MyObject>(myObjects );
}
private void GetMyObjectsRepository()
{
_connString = ConfigurationManager.ConnectionStrings["xxx"].ConnectionString;
_myObjectRepo = MyObjectRepositoryFactory.InstantiateRepo(_connString);
}
上面的问题听起来像是一个未来的问题——如果我创建一个不同的 ViewModel,它有自己的 BindableCollection<MyObject> _myObjects;
属性,那么相同对象的两个集合可能很快就会有不同的状态,即第一个是 ObjectX ViewModel 可能会更改其名称属性,但 ObjectX 在第二个 ViewModel 中仍具有其原始名称。
我想我可以在构建时将这个 <MyObject>
列表注入到 ViewModel 中 - 我应该在 Bootstrapper.cs
中这样做吗? (我宁愿避免完全成熟的 DI,因为这是一个小项目)
目前 Bootstrapper.cs
如下所示 - 如何将上述代码片段中的一些逻辑移至此处?它是否进入 OnStartUp
事件方法?如果是那么怎么办?
using Caliburn.Micro;
using Prototype_WPF.ViewModels;
using System.Windows;
namespace Prototype_WPF
{
public class Bootstrapper: BootstrapperBase
{
public Bootstrapper()
{
Initialize();
}
protected override void OnStartup(object sender, StartupEventArgs e)
{
DisplayRootViewFor<ShellViewModel>();
}
}
}
您可以创建一个单独的组件来检索您的对象,例如 IMyObjectService
并实现它。
public interface IMyObjectService
{
IList<MyObject> GetMyObjects();
}
然后在 Bootstrapper
中创建 Configure
方法的重载并注册一个实现,类似于:
protected override void Configure()
{
container = new SimpleContainer();
container.Singleton<IMyObjectService, MyObjectService>();
//other registrations
container.PerRequest<ShellViewModel>();
}
最后使用任何 ViewModel 的构造函数注入来注入和使用此服务。 Caliburn.Micro
文档已经有一些 examples
您可以使用 Handler
方法在引导程序中为您的视图模型注册工厂方法:
public class Bootstrapper : BootstrapperBase
{
private readonly BindableCollection<MyObject> _myObjects = new BindableCollection<MyObject>();
private SimpleContainer container;
public Bootstrapper()
{
Initialize();
}
protected override void Configure()
{
container = new SimpleContainer();
container.Singleton<IWindowManager, WindowManager>();
container.Handler<ShellViewModel>(_ => new ShellViewModel(_myObjects));
container.Handler<SomeOtherViewModel>(_ => new SomeOtherViewModel(_myObjects));
}
protected override void OnStartup(object sender, StartupEventArgs e)
{
DisplayRootViewFor(typeof(ShellViewModel));
}
protected override object GetInstance(Type service, string key)
{
return container.GetInstance(service, key);
}
protected override IEnumerable<object> GetAllInstances(Type service)
{
return container.GetAllInstances(service);
}
protected override void BuildUp(object instance)
{
container.BuildUp(instance);
}
}
您可以 'Register' 服务和 'Register' 每 class 如下
protected override void Configure()
{
container = new SimpleContainer();
container.Instance(container);
container
.Singleton<IMyObjectService, MyObjectService>();
//Register all ViewModel classes
GetType().Assembly.GetTypes()
.Where(type => type.IsClass)
.Where(type => type.Name.EndsWith("ViewModel"))
.ToList()
.ForEach(viewModleType => container.RegisterPerRequest(
viewModleType, viewModleType.ToString(), viewModleType));
}
我卡住了!
我正在使用 Caliburn.micro
来消除在 WPF
应用程序中实施 MVVM
的一些痛苦。
目前我只有一个 View / ViewModel,但将来可能会有多个 ViewModel。当前的 ViewModel 正在使用存储库来填充对象列表:
public class ShellViewModel : Screen
{
private IMyObjectRepository<IMyObject> _myObjectsRepo = null;
private BindableCollection<MyObject> _myObjects;
private string _connString;
/// <summary>
/// constructor
/// </summary>
public ShellViewModel()
{
//call the method which sets up the repository
GetMyObjectsRepository();
//following three lines cast the list from type IReport to type Report
var IMyObjects= _myObjectsRepo.GetAllIMyObjects();
var myObjects = IMyObjects.OfType<MyObject>().ToList();
MyObjects = new BindableCollection<MyObject>(myObjects );
}
private void GetMyObjectsRepository()
{
_connString = ConfigurationManager.ConnectionStrings["xxx"].ConnectionString;
_myObjectRepo = MyObjectRepositoryFactory.InstantiateRepo(_connString);
}
上面的问题听起来像是一个未来的问题——如果我创建一个不同的 ViewModel,它有自己的 BindableCollection<MyObject> _myObjects;
属性,那么相同对象的两个集合可能很快就会有不同的状态,即第一个是 ObjectX ViewModel 可能会更改其名称属性,但 ObjectX 在第二个 ViewModel 中仍具有其原始名称。
我想我可以在构建时将这个 <MyObject>
列表注入到 ViewModel 中 - 我应该在 Bootstrapper.cs
中这样做吗? (我宁愿避免完全成熟的 DI,因为这是一个小项目)
目前 Bootstrapper.cs
如下所示 - 如何将上述代码片段中的一些逻辑移至此处?它是否进入 OnStartUp
事件方法?如果是那么怎么办?
using Caliburn.Micro;
using Prototype_WPF.ViewModels;
using System.Windows;
namespace Prototype_WPF
{
public class Bootstrapper: BootstrapperBase
{
public Bootstrapper()
{
Initialize();
}
protected override void OnStartup(object sender, StartupEventArgs e)
{
DisplayRootViewFor<ShellViewModel>();
}
}
}
您可以创建一个单独的组件来检索您的对象,例如 IMyObjectService
并实现它。
public interface IMyObjectService
{
IList<MyObject> GetMyObjects();
}
然后在 Bootstrapper
中创建 Configure
方法的重载并注册一个实现,类似于:
protected override void Configure()
{
container = new SimpleContainer();
container.Singleton<IMyObjectService, MyObjectService>();
//other registrations
container.PerRequest<ShellViewModel>();
}
最后使用任何 ViewModel 的构造函数注入来注入和使用此服务。 Caliburn.Micro
文档已经有一些 examples
您可以使用 Handler
方法在引导程序中为您的视图模型注册工厂方法:
public class Bootstrapper : BootstrapperBase
{
private readonly BindableCollection<MyObject> _myObjects = new BindableCollection<MyObject>();
private SimpleContainer container;
public Bootstrapper()
{
Initialize();
}
protected override void Configure()
{
container = new SimpleContainer();
container.Singleton<IWindowManager, WindowManager>();
container.Handler<ShellViewModel>(_ => new ShellViewModel(_myObjects));
container.Handler<SomeOtherViewModel>(_ => new SomeOtherViewModel(_myObjects));
}
protected override void OnStartup(object sender, StartupEventArgs e)
{
DisplayRootViewFor(typeof(ShellViewModel));
}
protected override object GetInstance(Type service, string key)
{
return container.GetInstance(service, key);
}
protected override IEnumerable<object> GetAllInstances(Type service)
{
return container.GetAllInstances(service);
}
protected override void BuildUp(object instance)
{
container.BuildUp(instance);
}
}
您可以 'Register' 服务和 'Register' 每 class 如下
protected override void Configure()
{
container = new SimpleContainer();
container.Instance(container);
container
.Singleton<IMyObjectService, MyObjectService>();
//Register all ViewModel classes
GetType().Assembly.GetTypes()
.Where(type => type.IsClass)
.Where(type => type.Name.EndsWith("ViewModel"))
.ToList()
.ForEach(viewModleType => container.RegisterPerRequest(
viewModleType, viewModleType.ToString(), viewModleType));
}