Выбрать главу

  private readonly MyDatabaseDataContext _database;

  public MyDatabaseDataContext DataContext {

    get

    {

      return _database;

    }

  }

  private bool _disposed;

  public UnitOfWork()

  {

    _database = new MyDatabaseDataContext();

  }

  public void Commit()

  {

    _database.SubmitChanges();

  }

  public void Dispose()

  {

    Dispose(true); GC.SuppressFinalize(this);

  }

  private void Dispose(bool disposing) {

    if (!this._disposed)

    {

      if (disposing)

      {

        _database.Dispose();

      }

      _disposed = true;

    }

  }

}

Этот класс реализует паттерн UnitOfWork, который описывает реализацию атомарного действия, в данном случае создание контекста базы ORM, использование, сохранение изменений и разрушение объекта.

Пример использования слоя данных

Наша инъекция кода полностью реализована, рассмотрим вариант использования:

using (UnitOfWork unitOfWork = new UnitOfWork())

{

  ICustomerService customerService = new

    CustomerService(unitOfWork.DataContext);

  IOrderService orderService = new

    OrderService(unitOfWork.DataContext);

  IProductService productService = new

    ProductService(unitOfWork.DataContext);

  ICustomer customer = customerService.Create("Hoвый заказчик",

        "111-22-33", "Адрес нового заказчика");

  IProduct product = productService.Create("Новый товар", true, 50000);

  orderService.Create(customer, product, 200, DateTime.Now);

  unitOfWork.Commit();

}

Обратите внимание, в приведенном коде нет ни одной зависимости, которая привязывала бы нас либо к конкретной базе данных, либо к конкретному механизму ORM. Для замены одного из этих элементов нам потребуется всего лишь реализовать служебные механизмы вроде класса unitofWork, хранилищ и сервисов, согласно требованиям, но не приведенный код. Любой код, написанный с использованием описанных ранее механизмов, не потребует модернизации.

Еще одним хорошим ходом могло бы стать вынесение класса UnitofWork и контекста ORM в отдельные слабосвязанные сущности, для того чтобы хранилища и сервисы не были завязаны на определенные контексты ORM. Но в связи с тем, что хранилища и сервисы, по своей сути, жестко связаны с конкретным ORM, реализация такого вынесения требуется редко.

Механизмы для работы с данными

В реальных приложениях источник данных может быть самым разнообразным, чтобы продемонстрировать это, в текущем разделе мы приведем несколько механизмов для работы с данными и попробуем сравнить их производительность и простоту работы.

XML-данные

.NET Framework предлагает широкий ассортимент объектов для доступа к XML-данным, которые расположены в стандартных сборках: System.Xml, System.Xml.XPath, System.Xml.Xsl, System.Xml.Schema и System.Xml.Linq. Рассмотрим назначение и наиболее полезные классы каждой из сборок:

□ System.Xml — содержит базовые классы для работы с XML, такие как

XmlDocument, XmlElement, XmlNode и множество других, которые позволяют реализовать загрузку из файлов, обработку, добавление, изменение, удаление XML-данных;

□ System.Xml.XPath — содержит классы для реализации работы механизма XPath, позволяющего писать выражения к XML-документу для поиска необходимых данных;

□ System.Xml.Xsl — содержит классы для поддержки реализации XSLT-преобразований XML-документа;

□ System.Xml.Schema — содержит классы для поддержки XSD-схем и валидации XML-данных на их основе. Содержит большое число классов, позволяющих создавать XSD-схемы и использовать их;

□ System.Xml.Lin —  последняя сборка, которая недавно появилась в .NET Framework. Содержит классы, реализующие механизм доступа к XML-данным на основе LINQ-выражений. Этот механизм носит собственное название LINQ для XML. Он позволяет использовать уже известные вам LINQ-выражения для обработки XML-данных.

Рассмотрим пример обработки XML-данных с помощью LINQ для XML. Предположим, что у нас есть следующий XML-файл:

<?xml version="1.0"?>

<Orders>

  <Order OrderId="99" OrderDateTime="01.02.2009">

    <Address>

      <Name>Владимир Иванов</Name>

      <Street>yn. CTpoMTanefr</Street>

      <House>12</House>

      <Apartment>23</Apartment>

      <City>MocKBa</City>