В управляемом доменом дизайне это было бы нарушение DDD для помещения вызовов в repostiories других объектов в объекте области?

Есть способ использовать WindowsAPI.

$src = @"
[DllImport("KERNEL32.DLL")]
public static extern uint GetPrivateProfileString(string lpAppName, string lpKeyName, string lpDefault, System.Text.StringBuilder lpReturnedString, uint nSize, string lpFileName);
[DllImport("KERNEL32.DLL")]
public static extern uint WritePrivateProfileString(string lpAppName, string lpKeyName, string lpString, string lpFileName);
"@

Add-Type -MemberDefinition $src -Namespace WinApi -Name IniFileIO -Language CSharp

Function Read-IniFile ($Path, $Section, $Key) {
    $sb = [Text.StringBuilder]::new(1024)
    [WinApi.IniFileIO]::GetPrivateProfileString($Section, $Key, $null, $sb, $sb.Capacity, (Convert-Path -LiteralPath $Path)) > $null
    $sb.ToString()
}

Function Write-IniFile ($Path, $Section, $Key, $Value) {
    [WinApi.IniFileIO]::WritePrivateProfileString($Section, $Key, $Value, (Convert-Path -LiteralPath $Path)) >$null
}

Использование заключается в следующем.

Read-IniFile -Path "C:\sample.ini" -Section "Section1" -Key "Key1"
Write-IniFile -Path "C:\sample.ini" -Section "Section2" -Key "Key2" -Value "Hello"

Это случайный код, поэтому лучше использовать код, написанный mklement0 для фактического использования. Это более надежно.

8
задан Mark Rogers 2 March 2009 в 22:39
поделиться

5 ответов

У Вас не должно даже быть доступа к репозиториям от объекта области.

Тому, что можно сделать, или позволяют, сервис дает объекту области соответствующую информацию или имеет делегата в объекте области, который установлен сервисом или в конструкторе.

public DomainObject(delegate getApplicationsByBatchID)
{
    ...
}
5
ответ дан 5 December 2019 в 13:02
поделиться

Почему бы не передать в IList<VendorApplication> как параметр вместо VendorApplicationBatch? Код вызова для этого, по-видимому, прибыл бы из службы, которая будет иметь доступ к AppRepo. Тем путем Ваш доступ к репозиторию закончится, где он принадлежит, в то время как Ваша функция домена может остаться блаженно незнакомой о том, куда те данные прибыли из.

2
ответ дан 5 December 2019 в 13:02
поделиться

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

Править: Пример

Я пользуюсь библиотекой предприятия для простой проверки, таким образом, в классе объекта я установлю атрибут как так:

 [StringLengthValidator(1, 100)]
 public string Username {
     get { return mUsername; }
     set { mUsername = value; }
 }

Объект наследовался базовому классу, который имеет следующий метод "IsValid", который гарантирует, что каждый объект соответствует критериям проверки

     public bool IsValid()
     {
         mResults = new ValidationResults();
         Validate(mResults);

         return mResults.IsValid();
     }

     [SelfValidation()]
     public virtual void Validate(ValidationResults results)
     {
         if (!object.ReferenceEquals(this.GetType(), typeof(BusinessBase<T>))) {
             Validator validator = ValidationFactory.CreateValidator(this.GetType());
             results.AddAllResults(validator.Validate(this));
         }
         //before we return the bool value, if we have any validation results map them into the
         //broken rules property so the parent class can display them to the end user
         if (!results.IsValid()) {
             mBrokenRules = new List<BrokenRule>();
             foreach (Microsoft.Practices.EnterpriseLibrary.Validation.ValidationResult result in results) {
                 mRule = new BrokenRule();
                 mRule.Message = result.Message;
                 mRule.PropertyName = result.Key.ToString();
                 mBrokenRules.Add(mRule);
             }
         }
     }

Затем мы должны выполниться, этот метод "IsValid" в классе обслуживания сохраняют метод, как так:

 public void SaveUser(User UserObject)
 {
     if (UserObject.IsValid()) {
         mRepository.SaveUser(UserObject);
     }
 }

Более сложным примером мог бы быть банковский счет. Логика депозита будет жить в объекте учетной записи, но класс обслуживания назовет этот метод.

5
ответ дан 5 December 2019 в 13:02
поделиться

Насколько я понимаю (недостаточно информации, чтобы знать, является ли это правильным дизайном) VendorApplicationBatch должен содержать ленивый загруженный IList в объекте области, и логика должна остаться в домене.

Например (воздушный кодекс):

public class VendorApplicationBatch  {

    private IList<VendorApplication> Applications {get; set;};   

    public decimal CaculateBatchTotal()
    {
        if (Applications == null || Applications.Count == 0)
            throw new ArgumentException("There were no applications for this batch, that shouldn't be possible");

        decimal Total = 0m;
        foreach (VendorApplication App in Applications)
            Total += App.Amount;
       return Total;
    }
}

Это легко сделано с ORM как NHibernate, и я думаю, что это было бы лучшее решение.

1
ответ дан 5 December 2019 в 13:02
поделиться

Мне кажется, что ваш CalculateTotal является сервисом для коллекций VendorApplication's, и что возвращение коллекции VendorApplication's для Batch естественно подходит как свойство класса Batch. Таким образом, какой-нибудь другой сервис/контроллер/что бы то ни было извлекает соответствующую коллекцию VendorApplication из партии и передает ее сервису VendorApplicationTotalCalculator (или что-то в этом роде). Но это может нарушить некоторые правила агрегатного корневого сервиса DDD или что-то подобное, о чем я не знаю (новичок в DDD)

.
0
ответ дан 5 December 2019 в 13:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: