Как работают виртуальные прокси? - PullRequest
4 голосов
/ 15 июня 2011

У меня возникли проблемы с оборачиванием виртуальных прокси. Я прочитал тонны статей и потратил несколько часов, пытаясь найти хорошую информацию, но мне еще предстоит найти что-то всеобъемлющее. Поэтому я сделаю общий запрос здесь для получения более подробной информации (либо здесь, либо просто ссылка). Я также добавлю некоторые детали ниже, чтобы лучше объяснить, что именно я хочу.

У меня есть несколько объектов, и между ними много ссылок. Для краткости у меня будет один объект (узел) с базовыми отношениями родитель-ребенок. Когда я извлекаю этот объект из базы данных, я хотел бы реализовать отложенную загрузку. Из того, что я прочитал, виртуальный прокси-сервер по существу будет обрабатывать всю ленивую загрузку для меня, ссылаясь на интерфейс (INode) и вытягивая элементы данных по мере необходимости. [Примечание: на самом деле у меня нет класса INode, но когда я помещаю виртуальное ключевое слово в мои элементы данных, прокси-сервер действительно используется]

Когда я делаю элементы данных в моих классах виртуальными, кажется, что создается прокси. Это виртуальный прокси? Они реализуют отложенную загрузку?

Я искал информацию о виртуальном ключевом слове, но единственная документация, которую я смог найти, - это использовать ее для методов, которые используются для наследования, чтобы производные классы могли переопределить функцию, которая не имеет ничего общего с тем, что я хочу ( Я думаю).

Это мой текущий Node.cs

[DataContract(IsReference=true)]
public partial class Node
{
  [DataMember]
  public long ID { get; private set; }
  [DataMember]
  public virtual Node Parent { get; set; }
  [DataMember]
  public virtual ICollection<Node> Children { get; set; }
}

По сути, в этот момент я очень смущен, и мне просто нужно какое-то руководство по этой теме или даже онлайн-ресурс, на который я могу посмотреть, поскольку все, что я нашел, были менее чем полезны.

Заранее спасибо.

Ответы [ 2 ]

5 голосов
/ 16 июня 2011

«Виртуальный» прокси-сервер и отложенная загрузка связаны с инструментами ORM.Прокси на самом деле не является виртуальным, он динамический и соответствует реальному шаблону прокси, определенному GoF.

Динамический прокси - это класс, созданный инструментом ORM во время выполнения (он нигде не определен как файл кода).Он происходит от вашей сущности и переопределяет свойства навигации.Из-за этого они должны быть виртуальными, чтобы прокси работал.Прокси-сервер содержит свойство состояния навигации в закрытом поле или в любой более сложной структуре, и если к свойству обращаются впервые, он видит, что состояние выгружено, инициирует загрузку из базы данных и меняет состояние на загруженное.

В любом случаеЯ не уверен, как это относится к WCF, потому что лучшая практика - не использовать отложенную загрузку с WCF.Почему?

  • Если вы используете ленивую загрузку на стороне сервера, сериализация всегда извлекает из базы данных весь граф объектов, потому что сериализация получит доступ ко всем свойствам навигации и вызовет ленивую загрузку, но затем начнет сериализовать лениво загруженные объекты и доступвсе их свойства навигации и т. д.
  • Ленивая загрузка на стороне клиента - это что-то размытоеПрежде всего, ленивая загрузка на стороне клиента полностью зависит от вас - вы должны реализовать это.При использовании сервисов вы всегда должны следовать одному из принципов SOA: граница сервиса является явной.Это означает, что пользователь вашего объекта всегда должен знать, что он делает удаленный вызов вместо локального.Основной целью в распределенных вычислениях является уменьшение количества обращений к сети, поэтому вы должны использовать энергичную загрузку и по возможности передавать все необходимые данные в одном цикле, а не использовать отложенную загрузку.То же самое применимо для загрузки из базы данных - используйте ленивую загрузку, когда это имеет смысл, потому что обходы в базу данных могут быть дорогостоящими операциями.
1 голос
/ 15 июня 2011

Я думаю, вы хотите, чтобы некоторые личные поля поддерживали ваши виртуальные свойства В переопределениях get этих виртуальных свойств вы проверяете приватное поле, чтобы увидеть, действительно ли оно в настоящий момент (получено ли оно уже из db, обновлено ли оно и т. Д.) - если нет, то извлекает или повторно выбирает его. Я не вижу, что это должно быть более сложным, чем это.

Базовый класс:

private Node _Parent;
public virtual Node Parent { 
    get { return _Parent; } // Default no lazy fetch.
}

Override:

public override Node Parent {
    get {
        if (_Parent==null) // or out of date, dirty etc
            Do_db_get_of_parent();
        return _Parent;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...