注入数据访问依赖项以进行延迟加载的正确方法是什么? [英] What is the proper way to inject a data access dependency for lazy loading?
问题描述
在我进行延迟加载时注入数据访问依赖项的正确方法是什么?
What is the proper way to inject a data access dependency when I do lazy loading?
例如,我具有以下类结构
For example I have the following class structure
class CustomerDao : ICustomerDao
public Customer GetById(int id) {...}
class Transaction {
int customer_id; //Transaction always knows this value
Customer _customer = null;
ICustomerDao _customer_dao;
Customer GetCustomer() {
if(_customer == null)
_customer = _customer_dao.GetById(_customer_id);
return _customer
}
如何获取对_customer_dao的引用到事务对象中?如果我想让Transaction至少看起来像POCO,那么对于构造函数而言,这似乎没有任何意义.可以让Transaction对象直接引用控制容器的反转"吗?这似乎也很尴尬.
How do I get the reference to _customer_dao into the transaction object? Requiring it for the constructor seems like it wouldn't really make sense if I want the Transaction to at least look like a POCO. Is it ok to have the Transaction object reference the Inversion of Control Container directly? That also seems awkward too.
像NHibernate这样的框架如何处理呢?
How do frameworks like NHibernate handle this?
推荐答案
我建议使用其他方法... 使用延迟加载类:
I suggest something different... Use a lazy load class :
public class Lazy<T>
{
T value;
Func<T> loader;
public Lazy(T value) { this.value = value; }
public Lazy(Func<T> loader { this.loader = loader; }
T Value
{
get
{
if (loader != null)
{
value = loader();
loader = null;
}
return value;
}
public static implicit operator T(Lazy<T> lazy)
{
return lazy.Value;
}
public static implicit operator Lazy<T>(T value)
{
return new Lazy<T>(value);
}
}
一旦获得它,就不再需要将dao注入到对象中了:
Once you get it, you don't need to inject the dao in you object anymore :
public class Transaction
{
private static readonly Lazy<Customer> customer;
public Transaction(Lazy<Customer> customer)
{
this.customer = customer;
}
public Customer Customer
{
get { return customer; } // implicit cast happen here
}
}
创建未绑定到数据库的Transcation对象时:
When creating a Transcation object that is not bound to database :
new Transaction(new Customer(..)) // implicite cast
//from Customer to Lazy<Customer>..
从存储库中的数据库重新生成事务时:
When regenerating a Transaction from the database in the repository:
public Transaction GetTransaction(Guid id)
{
custmerId = ... // find the customer id
return new Transaction(() => dao.GetCustomer(customerId));
}
发生两件有趣的事情: -您的域对象可以在有或没有数据访问的情况下使用,它变得对数据访问无知.唯一的不足之处是允许传递一个函数,该函数提供对象而不是对象本身. -Lazy类是内部可变的,但可以用作不可变值. readonly关键字保留其语义,因为它的内容不能从外部更改.
Two interesting things happen : - Your domain objects can be used with or without data access, it becomes data acces ignorant. The only little twist is to enable to pass a function that give the object instead of the object itself. - The Lazy class is internaly mutable but can be used as an immutable value. The readonly keyword keeps its semantic, since its content cannot be changed externaly.
当您希望该字段可写时,只需删除readonly关键字.分配新值时,由于隐式强制转换,将使用新值创建一个新的Lazy.
When you want the field to be writable, simply remove the readonly keyword. when assigning a new value, a new Lazy will be created with the new value due to the implicit cast.
我在这里写过博客:
http://www.thinkbeforecoding .com/post/2009/02/07/Lazy-load-and-persistence-ignorance
这篇关于注入数据访问依赖项以进行延迟加载的正确方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!