Я создал класс модели POCO и класс репозитория, который обрабатывает постоянство. Поскольку POCO не может получить доступ к репозиторию, в репозитории существует множество задач бизнес-логики, которые не кажутся правильными. Из того, что я прочитал, похоже, что мне нужен уровень сервиса, который находится между потребителями пользовательского интерфейса и уровнем репозитория. Я не уверен в том, как именно он должен работать...
В дополнение к служебному уровню, должен ли быть также отдельный уровень бизнес-логики, или это роль уровня обслуживания?
Должна ли быть одна служба в репозитории?
Является ли сервисный уровень единственным способом, которым пользовательский интерфейс может экземпляр объектов модели или репозиторий предоставляет экземпляр новой модели службе?
Я помещаю свой параметр, модель и другие проверки на уровне службы, которые делают такие вещи, как проверка, чтобы убедиться, что вход действителен и что элемент обновления обновляется в базе данных до обновления?
Может ли модель, репозиторий и пользовательский интерфейс совершать вызовы на уровне сервиса, или это просто для пользовательского интерфейса?
Предполагается ли, что сервисный уровень является всеми статическими методами?
Каким будет типичный способ вызова уровня сервиса из пользовательского интерфейса?
Какие валидации должны быть для модели или уровня сервиса?
Вот пример кода для существующих слоев:
public class GiftCertificateModel
{
public int GiftCerticiateId {get;set;}
public string Code {get;set;}
public decimal Amount {get;set;}
public DateTime ExpirationDate {get;set;}
public bool IsValidCode(){}
}
public class GiftCertificateRepository
{
//only way to access database
public GiftCertificateModel GetById(int GiftCertificateId) { }
public List<GiftCertificateModel> GetMany() { }
public void Save(GiftCertificateModel gc) { }
public string GetNewUniqueCode() { //code has to be checked in db }
public GiftCertificateModel CreateNew()
{
GiftCertificateModel gc = new GiftCertificateModel();
gc.Code = GetNewUniqueCode();
return gc;
}
}
UPDATE: В настоящее время я использую веб-формы и классический ADO.NET. Я надеюсь, что в скором времени вы перейдете на MVC и EF4.
ОБНОВЛЕНИЕ: Большое спасибо @Lester за его великое объяснение. Теперь я понимаю, что мне нужно добавить сервисный уровень для каждого из моих репозиториев. Этот уровень будет ТОЛЬКО способом, с помощью которого пользовательский интерфейс или другие службы могут связываться с репозиторием и будут содержать любые проверки, которые не подходят для объекта домена (например, - проверки, которые должны вызывать репо)
public class GiftCertificateService()
{
public void Redeem(string code, decimal amount)
{
GiftCertificate gc = new GiftCertificate();
if (!gc.IsValidCode(code))
{
throw new ArgumentException("Invalid code");
}
if (amount <= 0 || GetRemainingBalance(code) < amount)
{
throw new ArgumentException("Invalid amount");
}
GiftCertificateRepository gcRepo = new GiftCertificateRepository();
gcRepo.Redeem(code, amount);
}
public decimal GetRemainingBalance(string code)
{
GiftCertificate gc = new GiftCertificate();
if (!gc.IsValidCode(code))
{
throw new ArgumentException("Invalid code");
}
GiftCertificateRepository gcRepo = new GiftCertificateRepository();
gcRepo.GetRemainingBalance(code);
}
public SaveNewGC(GiftCertificate gc)
{
//validates the gc and calls the repo save method
//updates the objects new db ID
}
}
Вопросы
-
Я добавляю те же (и, возможно, больше) свойства к службе, как у меня на моей модели (количество, код и т.д.), или я предлагаю только методы, которые принимают объекты GiftCertificate и прямые параметры?
-
Создать экземпляр по умолчанию объекта GiftCertificate при вызове конструктора службы или просто создать новые по мере необходимости (например, для методов проверки в службе, которые должны вызывать методы проверки в сущности? Кроме того, тот же вопрос о создании экземпляра репозитория по умолчанию...?
-
Я знаю, что я раскрываю функциональность репо через службу, также я также выставляю методы из объекта (например, IsValidCode и т.д.)?
-
Это нормально для пользовательского интерфейса, чтобы просто создать новый объект GiftCertificate напрямую, не проходя через службу (например, - для вызова методов проверки параметров из объекта). Если нет, как обеспечить его соблюдение?
-
На уровне пользовательского интерфейса, когда я хочу создать новый подарочный сертификат, я могу вызвать валидации модели/услуги (например, IsValidExpirationDate и т.д.) непосредственно из уровня пользовательского интерфейса или сначала увлажнить объект, а затем передать он должен быть проверен, а затем возвратить какое-то подтверждение валидации обратно в пользовательский интерфейс?
Кроме того, если я хочу переустановить из уровня пользовательского интерфейса, я сначала вызываю методы проверки модели/службы из пользовательского интерфейса, чтобы дать пользователю обратную связь, а затем вызвать метод Redeem, который будет повторять те же проверки снова внутри?
Пример вызова службы для выполнения операции Redeem из пользовательского интерфейса:
string redeemCode = RedeemCodeTextBox.Text;
GiftCertificateService gcService = new GiftCertificateService();
GiftCertificate gc = new GiftCertificate(); //do this to call validation methods (should be through service somehow?)
if (!gc.IsValid(redeemCode))
{
//give error back to user
}
if (gcService.GetRemainingBalance(redeemCode) < amount)
{
//give error back to user
}
//if no errors
gcService.Redeem(code,amount);
Пример создания нового подарочного сертификата из пользовательского интерфейса:
GiftCertificateService gcService = new GiftCertificateService();
GiftCertificate gc = new GiftCertificate();
if (!gc.IsValidExpDate(inputExpDate))
{
//give error to user..
}
//if no errors...
gc.Code = gcService.GetNewCode();
gc.Amount = 10M;
gc.ExpirationDate = inputExpDate;
gcService.SaveNewGC(gc);
//method updates the gc with the new id...
Что-то кажется неправильным в отношении того, как создаются GC и как разделяются проверки между сущностью/службой. Пользователь/потребитель не должен беспокоиться о том, какие валидации в каком месте... совет?