我正在使用来自compisition root的IoC容器和对象组合开发应用程序。目标是通过推迟ViewModel属性的初始化来最小化对象构建的时间。
由于我对IoC世界很陌生,我最初的方法是在构造函数中调用IRepository
并填充属性。但这会在对象组合期间导致大量调用。
我不想创建Initialize
方法,因为调用它可能会被遗忘并导致无效的对象状态。
我正在考虑使用Lazy<>
进行延迟初始化,如下所示:
readonly Lazy<IEnumerable<Customer>> _lazyCustomers;
public virtual IEnumerable<Customer> Customers => _lazyCustomers.Value;
public ReportViewModel(IReportRepository repository)
{
_lazyCustomers = new Lazy<IEnumerable<Customer>>(repository.GetCustomers);
}
这看起来很有希望,但如果该属性有一个setter我必须提出一个额外的字段,因为我无法设置一个懒惰的值:
<IEnumerable<Customer> _customers;
readonly Lazy<IEnumerable<Customer>> _lazyCustomers;
public virtual IEnumerable<Customer> Customers {
get { return _customers ?? (_customers = _lazyCustomers.Value); }
set { _customer = value; }
}
从我的角度来看,这种外观看起来过于复杂。我可以完全摆脱Lazy<>
并直接调用属性的getter中的IReportRepository
。
什么是属性初始化的好模式(在对象构建之后)?这太复杂了,我应该坚持使用Initialize
方法吗?
答案 0 :(得分:1)
你在这里遇到的问题与IOC无关。你不应该在构造函数中调用像GetCustomers这样的调用。
如果要缓存客户(这将在第一次调用时从存储库加载客户,然后再使用私有变量),您可以执行以下操作:
private IEnumerable<Customer> _customers;
public IEnumerable<Customer> Customers {
get {
if (_customers == null)
{
_customers = _customerRepository.GetCustomers();
}
return _customers;
}
}
public AddCustomer(Customer customer) {
if (_customers == null)
{
_customers = _customerRepository.GetCustomers();
}
_cusomers.Add(customer);
}