Внедрение зависимостей со статическими классами и свойствами - PullRequest
1 голос
/ 14 сентября 2011

Я разработал многоуровневое решение и создал группу Manager классов для реализации бизнес-логики. Все менеджеры являются производными от BaseManager класса. Чтобы быть более понятным, вот UserManager класс:

public class UserManager : BaseManager
{
    public void Add(User user)
    {
       ...
    }
    public void Update(User user)
    {
       ...
    }
    public void Delete(User user)
    {
       ...
    }
    public bool GetAccessPermissions(User user)
    {
       ...
    }
}  

BaseManager выглядит следующим образом:

public class BaseManager
{  
    protected IRepository repository = IoCLocator.Resolve<IRepository>();
    public BaseManager()
    {
        ...
    }
    // Some shared methods among manager classes.
}  

Теперь я скептически отношусь к тому, что все мои классы менеджера должны быть определены как статические, так как они получают связанные объекты, с которыми они хотят работать, в качестве параметров. Но, как вы видите, у меня есть несколько общих частных / защищенных членов, которых я должен создавать при каждом звонке. (например, repository должен быть создан при создании каждого класса менеджера).

Как я могу определить классы менеджеров как статические, и при этом защищенные члены создаются при каждом вызове методов менеджеров?

Ответы [ 2 ]

2 голосов
/ 14 сентября 2011

Вам нужны классы менеджера, чтобы они были статичными, или вы просто хотите, чтобы они были одиночками?

Вы ищете способ иметь одноэлементный класс с переходными зависимостями?

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

Виндзор предлагает типизированный завод, который помогает в создании таких заводов: http://docs.castleproject.org/Windsor.Typed-Factory-Facility-interface-based-factories.ashx

2 голосов
/ 14 сентября 2011

У вас есть несколько вариантов здесь:

1)

 public class BaseManager
    {  
        protected IRepository repository;
        public BaseManager(IRepository _repository)
        {
            repository = _repository 
        }
        // Some shared methods among manager classes.
    }  

Для этого необходимо создать экземпляр BaseManager, используя

IoCLocator.Resolve<BaseManager>();

или что-то в этом роде, в зависимости от конкретного IoCLocator (MEF, Unity, Ninject или что вы используете)

2) Почти то же самое:

 public class BaseManager
     {  
        protected IRepository repository;
        public BaseManager(IoCLocator locator)
        {
            repository = locator.Resolve<IRepository>();
        }
        // Some shared methods among manager classes.
     } 

3) Или ввести свойство напрямую

 public class BaseManager
 {  
    [InjectFromContainer]
    protected IRepository repository {get;set;}

    public BaseManager()
    {
        repository = locator.Resolve<IRepository>();
    }
    // Some shared methods among manager classes.
 }  

Я не могу точно назвать нужный вам Атрибут, потому что он зависит от вашего контейнера. В любом случае вам придется создать экземпляр контейнера IoC в BootStrapper, зарегистрировать в нем BaseManager и затем разрешить его экземпляр из контейнера.

Надеюсь, это поможет, Илья

UPDATE:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...