我有一个简单的要求要达到。基本上,我有一个包含企业列表的视图。业务列表的属性包含在我的viewmodel类中,该类又绑定到该视图。这是带有业务列表的简单MVC应用程序。
但是,我遇到的问题是,我派生了另一个类的业务列表,该类依赖于视图模型,并且该类基本上类似于我称为BusinessService的存储库。繁忙的服务由异步方法组成,这是我的难题,当从viewModel的Ctor或属性的getter进行调用时,我的应用程序挂起。该呼叫也是在业务服务内非常规的EF数据库,因此不确定哪种正确方法是正确的。请参见下面的代码:
ViewModel:
#region Ctor
public BusinessListViewModel(IBusinessService businessService, IStringBuilder builder)
{
_businessService = businessService;
_builder = builder;
InitBusinesses().Wait(); //OPTION 1
}
#endregion
#region Properties
public IEnumerable<BusinessViewModel> _businesses;
public IEnumerable<BusinessViewModel> Businesses
{
get
{
if (_businesses == null)
{
InitBusinesses().Wait(); //OPTION 2
}
return _businesses;
}
set => _businesses = value;
}
private async Task InitBusinesses()
{
var response = await _businessService.Get();
Businesses = response.IsSuccessful
? response.Data.Select(p => new BusinessViewModel(_builder, p))
: new List<BusinessViewModel>();
}
业务服务:
#region Service Methods
public async Task<Response<IEnumerable<Models.Business>>> Get()
{
var data = await Db.Businesses.ToListAsync();
return new Response<IEnumerable<Models.Business>>
{
IsSuccessful = true,
Message = "Successful",
Data = Mapper.Map<List<Models.Business>>(data)
};
}
请您告知最佳模式和正确方法,我已经知道这是错误的>谢谢
答案 0 :(得分:1)
当UI框架要求您的代码显示某些内容时,必须立即(同步)显示它。 ViewModel构造函数和数据绑定属性应该是同步的和立即的。根本不可以进行网络I / O。即使您可以正常工作(可能),所有要做的就是阻止UI线程,从而降低用户体验。
一个更合适的解决方案是同步初始化进入加载状态(“ Loading ...”消息,微调框等),并启动异步操作。然后,当操作完成时,使用实际数据更新 UI。
答案 1 :(得分:0)
您应该考虑使用返回Task
的工厂方法
private BusinessListViewModel(IBusinessService businessService, IStringBuilder builder)
{
_businessService = businessService;
_builder = builder;
}
public static async Task<BusinessListViewModel> Create(IBusinessService businessService, IStringBuilder builder)
{
var instance = new BusinessListViewModel(businessService, builder)
await InitBusiness();
return instance;
}