Как реализовать IoC в иерархическом классе - PullRequest
2 голосов
/ 11 марта 2011

У меня есть иерархический список категорий с объектами категории

public class Category
    {
        private int? ParentId = -1;

        private Category _Parent = null;
        public Category Parent
        {
            get
            {
                if (_Parent != null)
                {
                    return _Parent;
                }

                if (this.ParentId.HasValue)
                { 

                    ICategoryRepository repo = new CategoryRepository();
                    var data = repo.Get(this.ParentId.Value); 

                    _Parent = data;
                }
                return _Parent;
            }
            set
            {
                _Parent = null;
                if (value == null)
                {
                    ParentId = null;
                }
                else
                {
                    ParentId = value.Id;
                }
            }
        }

Каждая категория имеет свойство Parent, которое лениво загружает свою родительскую категорию.

Исходная категория загружается с использованием интерфейса IRepository, поэтому мне никогда не придется создавать новый экземпляр репозитория на бизнес-уровне, они предоставляются на уровне приложения через внедрение зависимостей с использованием Unity, ninject и т. Д.

Но здесь я вижу случай, когда мне нужно создать экземпляр хранилища из бизнес-уровня. Как бы я изменил этот дизайн?

Ответы [ 4 ]

1 голос
/ 11 марта 2011

Может оказаться полезным использование подхода Lazy , как объяснено здесь .Это довольно хороший подход к разрешению отложенной загрузки при сохранении постоянства вне класса бизнес-объектов.

0 голосов
/ 11 марта 2011

Интересный вопрос. Как насчет чего-то вроде этого:

public class Category
{
   public int? ParentID{get;set;}
}

public class CategoryRepository
{
   public Category Get(int id)
   {
      Category result = GetFromDBAlongWithParentID(id);
   }

   public Category GetParent(Category child)
   {
      return child.ParentID.HasValue ? (Category)null : this.Get(child.ParentID.Value);
   }
}

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

0 голосов
/ 11 марта 2011

Роберт Леви ответит сразу после прочтения вашего вопроса.Если вы не хотите создавать жесткую зависимость от инфраструктуры DI из своего бизнес-уровня, вы можете сделать хранилище свойством объекта Category и установить это свойство при создании объекта хранилища в repo.Get.Это выглядит довольно отвратительно, хотя вам не обязательно нужна эта ссылка (если вы никогда не ленивый груз), а также она «жестко запрограммирована», т.е. не использует DI как таковой.В качестве альтернативы вы можете использовать отложенное разрешение, как описано здесь http://msdn.microsoft.com/en-us/library/ff660854%28PandP.20%29.aspx Таким образом, когда вы создаете объект категории, вы также получаете делегат преобразователя, который объект категории сможет вызывать, если ему потребуется разрешить экземпляр репозитория..

0 голосов
/ 11 марта 2011

Переместить 'repo', чтобы он был закрытым членом класса Category.Установите его значение с помощью внедрения зависимости (не добавляйте его в геттер).Убедитесь, что ваш метод IRepository.Get работает с вашей структурой внедрения зависимостей для создания возвращаемых объектов (так что в этом случае будет установлено 'repo').

...