Я в процессе пересмотра моего текущего проекта, чтобы быть более ремонтопригодным, и прилагаю все усилия, чтобы следовать хорошей практике проектирования. В настоящее время у меня есть решение с компонентом Silverlight, хостом ASP.Net для упомянутого приложения SL, которое также содержит службу WCF RIA и библиотеку с общим классом, поэтому SL и WCF-служба могут обмениваться объектами. Бизнес-логика разбросана по всему месту, и все операции CRUD кодируются вручную в моих WCF-сервисах. Итак, я создаю новую структуру для всего и переношу этот беспорядок в новый формат. В процессе выполнения этого я нахожу, что я дублирую классы, когда не знаю, должен ли я быть.
Моя новая структура выложена как таковая:
Клиент:
Reporting.Silverlight = приложение Silverlight. Это будет ссылка на мои классы DTO.
Reporting.Web = держит мое приложение SL и является основной точкой входа для людей, чтобы добраться до него.
Бизнес:
Reporting.Services = Мои службы WCF живут здесь. Мое приложение SL сделает вызовы для этого, чтобы сделать материал, и эти службы вернут классы DTO.
Reporting.Services.Contracts = Удерживает мои интерфейсы для служб WCF и содержит классы DTO с декораторами DataContract.
Reporting.Domain = хранит мои объекты домена и бизнес-логику
Данные:
Reporting.Data.Contract = хранит мои интерфейсы для хранилища и единицы работы
Reporting.Data = Конкретная реализация репозитория /UoW. Контекст Entity Framework 5 определен здесь.
Reporting.Data.Models = Сохраняет все мои объекты Entity, поэтому EF5 может выполнять свою задачу с помощью SQL.
У меня 3 места, где у меня почти такой же класс, и для меня это пахнет. Внутри Reporting.Services.Contracts У меня есть DTO, который передается клиенту SL. Вот пример:
[DataContract(Name = "ComputerDTO")]
public class ComputerDTO
{
[DataMember(Name = "Hostname")]
public string Hostname { get; set; }
[DataMember(Name = "ServiceTag")]
public string ServiceTag { get; set; }
// ... lots more
}
Я думаю, что вышеупомянутый DTO прекрасен, поскольку это всего лишь куча свойств, которые передаются клиенту SL. Подавляющее большинство моих свойств DTO сопоставляются с собственными объектами объектов Entity 1:1, за исключением полей ID. Вот мой объект Entity, который соответствует указанному выше DTO:
[Table("Inventory_Base")]
public class ComputerEntity
{
// primary key
[Key]
public int AssetID { get; set; }
// foreign keys
public int? ClientID { get; set; }
// these props are fine without custom mapping
public string Hostname { get; set; }
public string ServiceTag { get; set; }
// ... plus a bunch more in addition to my navigation properties
}
Я использую первый подход кода с EF5. Я все еще нахожусь на начальных этапах моей перезаписи, и до сих пор у меня сложилось впечатление, что бизнес-логика НЕ должна быть внутри моего EF Entity. У DTO также не должно быть бизнес-логики. Это означает, что он входит в мою модель домена, верно? Ну, это дает мой третий почти идентичный класс в Reporting.Domain
public class Computer
{
public string Hostname { get; set; }
public string ServiceTag { get; set; }
// ... lots more, pretty much mirrors the DTO
public string Method1(string param1)
{
// lots of methods and logic go in here
}
}
Имея 3 почти одинаковых класса, возможно, не может быть правильным способом, чтобы это сделать, не так ли? Должен ли я помещать всю свою бизнес-логику в объект EF, а затем проецировать результат в DTO, который проходит через провод? Если было бы хорошей идеей перерезать всю мою доменную/бизнес-логику внутри классов сущностей EF, структурно я должен перенести эту сборку на свой бизнес-уровень и за пределы моего уровня данных, даже если эти объекты будут сохранены в моей базе данных? В идеале я пытаюсь сохранить ссылки на Entity Framework, содержащиеся в моих проектах с данными и вне моих бизнес-проектов. У меня около 200 или около того классов, которые я переношу и буду содержать мой домен, и я ожидаю, что эта вещь будет масштабироваться до гораздо большей функциональности, как только я получу эту перезапись. Любое понимание того, как структурировать эту вещь и сохранить ее DRY, было бы высоко оценено.
В случае, если это поможет определить, что я пытаюсь сделать лучше, сообщите мне, следует ли мне включить мою методологию репозитория /unitofwork, за которой я следую.