注入数据访问依赖项以进行延迟加载的正确方法是什么? [英] What is the proper way to inject a data access dependency for lazy loading?

查看:58
本文介绍了注入数据访问依赖项以进行延迟加载的正确方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我进行延迟加载时注入数据访问依赖项的正确方法是什么?

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆