Главная страница   /   15.3. Исследование ядра (ASP.NET MVC 4 в действии

ASP.NET MVC 4 в действии

ASP.NET MVC 4 в действии

Джеффри Палермо

15.3. Исследование ядра

Доменная модель – самая важная часть приложения. Без доменной модели все соответствующие понятия были бы представлены только в пользовательском интерфейсе. Наша конкретная доменная модель содержит единичный агрегат, состоящий из единичного объекта, Visitor.

Ниже представлен код класса Visitor.

Листинг 15-1: Класс Visitor, доменная модель данного примера
using System;
namespace Core
{
	public class Visitor
	{
		public Guid Id { get; set; }
		public string PathAndQuerystring { get; set; }
		public string LoginName { get; set; }
		public string Browser { get; set; }
		public DateTime VisitDate { get; set; }
		public string IpAddress { get; set; }
	}
}

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

Класс Visitor содержит свойства для каждого вида информации, которую нам хотелось бы записать. Свойство Id существует в качестве идентификатора конкретного посещения. Мы точно могли бы использовать Int32 в качестве ID, но в среде хранения данных, которая вынуждает использовать зависимость от хранилища данных при генерации уникального значения Int32. Иногда это приемлимо, но в DDD разработчик допускает ошибку в том плане, что отдает всю ответственность доменной модели, а не хранилищу данных. В соответствии с этим Id – это Guid, и приложение будет генерировать Guid перед тем, как попытаться выполнить сохранение в базу данных.

Механизм сохранения или извлечения Visitor называется репозиторием. Репозиторий будет сохранять наш объект, а также извлекать его. Он также может исполнять операции фильтрации. В нашей доменной модели есть IVisitorRepository:

Листинг 15-2: Репозиторий, который определяет операции сохранения
namespace Core
{
	public interface IVisitorRepository
	{
		void Save(Visitor visitor);
		Visitor[] GetRecentVisitors(int numberOfVisitors);
	}
}

С помощью нашего репозитория мы можем сохранить Visitor, а также получить конкретное количество самых последних посетителей. На рисунке 15-4 вы можете видеть, что проект Core не содержит ни одного класса, реализующего IVisitorRepository. Это важно, поскольку класс, который выполняет работу, представленную интерфейсом, будет ответственным за сохранение, что не является заботой доменной модели. Сохранение – это инфраструктура. Данная функциональность работала бы одинаково хорошо, если бы мы сохраняли данные в файл, а не в базу данных. Механизм сохранения не входит в компетенции доменной модели, поэтому и класс, ответственный за него, отсутствует в проекте Core.

То, что находится в проекте Core, – это абстрактная фабрика, способная размещать или создавать экземпляры IVisitorRepository. VisitorRepositoryFactory отвечает за возврат экземпляра нашего репозитория. Следующий листинг иллюстрирует тот факт, что знания, необходимые для создания репозитория, не расположены в рамках фабрики. Эта фабрика просто олицетворяет способность возврата репозитория.

Листинг 15-3: Фабрика, которая предоставляет репозиторий
using System;
namespace Core
{
	public class VisitorRepositoryFactory
	{
		public static Func<IVisitorRepository> RepositoryBuilder = 
			CreateDefaultRepositoryBuilder;

		private static IVisitorRepository CreateDefaultRepositoryBuilder()
		{
			throw new Exception("No repository builder specified.");
		}

		public IVisitorRepository BuildRepository()
		{
			IVisitorRepository repository = RepositoryBuilder();
			return repository;
		}
	}
}

Строка 6-7: Инициализируется при запуске приложения

Строка 11: Выдается в случае, если фабрика не проинициализирована

Строка 16: Использует делегирование для создания репозитория

Даже для неопытного глаза этот класс кажется не столь полезным в одиночку. При вызове BuildFactory() выдается исключение. Доменная модель не знает, какая реализация IVisitorRepository будет использоваться, поэтому нет способа вложить это знание в скомпилированный код. В свойстве public static RepositoryBuilder необходимо будет задать что-то полезное перед тем, как фабрика заработает должным образом. Мы рассмотрим то, как это выполняется после того, как ознакомимся со всем необходимым.

Данная конкретная фабрика не нужна, если вы используете IoC-контейнер, который был пропущен для простоты. Эта доменная модель умышленно является простой.

Следующий шаг – понять, как настроить NHibernate для автоматического сохранения нашего объекта в базу данных.