我正在使用WinForms应用程序中的MVP实现。我的Presenter类将视图和模型都作为构造函数参数。然后,它在视图上设置模型属性,调用数据绑定并显示视图。我的模型需要一些服务来实例化,并且具有相同的工厂方法。我的演示者有一个工厂方法来接收此模型,并通过注册解析视图参数。这是代码示例:
public class Presenter{
public delegate Presenter Factory(ViewModel viewModel);
public Presenter(ViewModel viewModel, IView<ViewModel> view){
view.ViewModel = viewModel;
view.BindModel();
view.Show();
}
}
public class ViewModel{
public delegate ViewModel Factory(int modelId);
//This collection is used by WinForms to show dropdown list
//and selected value is set as parent id on model
public IEnumerable<Parent> ParentPropertyCollection {get; set;}
//This constructor create a new model
public ViewModel(IModelRepository repository, IParentRepository parentRepository){
//Initiate the parent collection using parentRepository for selection through dropdown on form. repository is used for sending the updates back.
}
//This constructor fetches existing model
public ViewModel(int modelId, IModelRepository repository,
IParentModelRepository parentRepository){
//fetch model data and set model properties using repository
//Also populate parent collection.
}
}
public class Navigator{
public Navigator(IContainer container){
_container = container;
}
public void ShowModelForm(int modelId){
var modelFactory = container.Resolve<ViewModel.Factory>;
var model = modelFactory(modelId);
var presenterFactory = container.Resolve(Presenter.Factory);
var presenter = presenterFactory(model);
}
public void NewModelForm(){
var model = _container.Resolve<ViewModel>();
var presenterFactory = container.Resolve<Presenter.Factory>();
var presenter = presenterFactory(model);
}
适应这种结构的原因很少。我不希望多个演示者用于新的和编辑模型场景。有许多实体,并为每个操作创建单独的演示者只是太多的工作。其次,我不能在演示者中有多个参数,因为Autofac给了我错误,它无法选择工厂的构造函数。第三,我没有将存储库参数添加到演示者,因为它不需要依赖它们,只是因为模型需要它们。
[编辑:为了清晰起见,添加了更多代码。修复了ViewModel类的问题]
public interface IView<T> where T:class{
T ViewModel {get; set;}
BindModel();
}
我做依赖性解析的方式非常标准。我不希望容器到处注入。我在启动代码中进行注册,并将容器传递给Navigator类以进行解析。 Navigator通常位于模块级别并处理模块内的导航。
以下是上述代码的分辨率片段
builder.RegisterType<ViewModel>();
builder.RegisterType<ModelForm>().As<IView<ViewModel>>();
builder.RegisterType<Presenter>();
builder.RegisterType<Navigator>();
builder.Register(c=> _container).As<IContainer>();
[编辑完成]
面对我所面临的问题,当我将vm参数传递给现有模型的演示者时,它会正确创建并传递模型。但是,在演示者内部,在解析IView时,它会再次为新的空模型实例实例化视图模型,并将新实例分配给查看而不是由演示者传递。我不确定为什么会这样。