powered by simpleCommunicator - 2.0.59     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / ASP.NET [игнор отключен] [закрыт для гостей] / IoC. Постепенный перевод проекта. Возможно ли
47 сообщений из 47, показаны все 2 страниц
IoC. Постепенный перевод проекта. Возможно ли
    #38628469
Pavluha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Попробовал перевести проект на IoC. но не сразу все, а постепенно.
Возможно ли такое или придется все сразу переделывать?

И еще вопрос с реализацией. Использую Autofac пока. На нем тренируюсь.
Начал с репозиторий. Взял 1 из репозиторий, она является самостоятельным классом и реализовал интерфейс.
Теперь класс выглядит так:

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
 internal class UserRepository : IUserRepository
	{
		private ModelDataContext _dataManager;

		public UserRepository(ModelDataContext DataContext)
		{
			_dataManager = DataContext;
		}
..........................................



Прописал при запуске конфигурацию IoC
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
private static void ConfigureIoC()
        {
            var builder = new ContainerBuilder();
            builder.RegisterControllers(Assembly.GetExecutingAssembly());

            // register repositories
            builder.RegisterType<UserRepository>().As<IUserRepository>().InstancePerHttpRequest();

            IContainer container = builder.Build();
            DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); 
        }



Теперь вопрос, как поступить вот с этим:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
public class DataManager
	{
		private ModelDataContextWrapper _dataContext;
		public DataManager()
		{
			_dataContext = new ModelDataContextWrapper();
		}

        private IUserRepository _userRepository;
        public IUserRepository Users;
		{
			get 
			{
				if (null == _userRepository)
					_userRepository = new UserRepository(_dataContext);

				return _userRepository;
			}
		}



Если я все правильно понимаю, то данный класс должен быть также наследовать интерфейс IDataManager?
Что здесь лишнее или что я забыл, чтобы часть, а именно UserRepository заработала, как DI?
...
Рейтинг: 0 / 0
IoC. Постепенный перевод проекта. Возможно ли
    #38628586
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PavluhaВозможно ли такое или придется все сразу переделывать?

возможно. но рекомендую задаться целью, для чего вам нужен DI, и какие преимуществ конкретно вы хотите добиться? так вам будет проще, чем тупо "переводить всё на DI".


PavluhaЧто здесь лишнее или что я забыл, чтобы часть, а именно UserRepository заработала, как DI?

старайтесь передавать зависимости через конструктор:

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
        public class DataManager : IDataManager
	{		
                public DataManager(IUserRepository repository)
		{
			// _dataContext = new ModelDataContextWrapper(); --- НЕТ!
                        _userRepository = repository;  // ДА!
		}

        private IUserRepository _userRepository;
...
Рейтинг: 0 / 0
IoC. Постепенный перевод проекта. Возможно ли
    #38628591
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Pavluha,

если где-то получается, что компонент требует много зависимостей (и вам кажется, что конструктор от этого распух), значит проблема в архитектуре.

также постарайтесь избежать "аггрегатора" зависимостей, собирающего кучу зависимостей и раздающего направо и налево. лучше передать фабрику на базе DI-контейнера.

Autofac, кстати, хороший выбор.
...
Рейтинг: 0 / 0
IoC. Постепенный перевод проекта. Возможно ли
    #38628637
Pavluha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
hVostt,

Сейчас сделал так и пока работает, но хотелось бы комментариев на правильность:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
public interface IDataManager: IDisposable
    {
        ModelDataContextWrapper Get();
    
        IUserRepository Users { get; }
}
public class DataManager: IDataManager, IDisposable
	{
		private ModelDataContextWrapper _dataContext;
		public DataManager()
		{
			Get();
		}
private IUserRepository _userRepository;
        public IUserRepository Users
        {
            get
            {
                if (null == _userRepository)
                    _userRepository = DependencyResolver.Current.GetService<IUserRepository>();

                return _userRepository;
            }
        }

public ModelDataContextWrapper Get()
        {
            return _dataContext ?? (_dataContext = new ModelDataContextWrapper());
        }
...
Рейтинг: 0 / 0
IoC. Постепенный перевод проекта. Возможно ли
    #38628678
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PavluhaСейчас сделал так и пока работает, но хотелось бы комментариев на правильность:

плохо.

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
        private IUserRepository _userRepository;
        public IUserRepository Users
        {
            get
            {
                if (null == _userRepository)
                    _userRepository = DependencyResolver.Current.GetService<IUserRepository>();

                return _userRepository;
            }
        }



получайте IUserRepository через конструктор (как я показал выше).

и постарайтесь свести использование DependencyResolver к минимуму. желательно, чтобы он вообще не появлялся, ну кроме тех мест, где механизм разрешения зависимостей DI недоступен (например, в HttpApplication).

и ещё один момент. у вас IDataManager выполняет роль DI, отдавая ModelDataContextWrapper с помощью метода Get(). зачем? получайте свой ModelDataContextWrapper точно также через DI. или через фабрику. а вообще при использовании репозитория, дата контекст вообще не нужен.
...
Рейтинг: 0 / 0
IoC. Постепенный перевод проекта. Возможно ли
    #38628795
Pavluha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
hVosttполучайте свой ModelDataContextWrapper точно также через DI

А пример можно?
Просто у меня модель используется DBML не EF. В инете ничего путного не нашел.
А сам DataManager это менеджер репозиторий с lazy инициализацией.
...
Рейтинг: 0 / 0
IoC. Постепенный перевод проекта. Возможно ли
    #38628806
Pavluha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
hVostt,

Вроде начал догонять.
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
public class DataManager : IDataManager
	{		
                public DataManager(IUserRepository repository)
		{
                        _userRepository = repository;  // ДА!
		}

        private IUserRepository _userRepository;



У меня репозиторий вот столько:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
public interface IDataManager: IDisposable
    {
        ModelDataContextWrapper Get();
    
        IUserRepository Users { get; }
        RoleRepository Roles { get; }
        CDMRepository CDMs { get; }
        CommandRepository Commands { get; }
        AuditRepository Audits { get; }
        MonitoringRepository Monitorings { get; }
        SettingRepository Settings { get; }

        void SubmitChanges();
    }



Их все в конструкторе указывать?
...
Рейтинг: 0 / 0
IoC. Постепенный перевод проекта. Возможно ли
    #38628875
Pavluha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Фабрику реализовал:

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
public class DatabaseFactory : IDisposable, IDatabaseFactory
    {
        private ModelDataContextWrapper _entityContext;
        public ModelDataContextWrapper Get()
        {
            return _entityContext ?? (_entityContext = new ModelDataContextWrapper());
        }

        public void Dispose()
        {
            if (null != _entityContext)
                _entityContext.Dispose();
        }
    }



Теперь вообще запутался, куда и как ее прикручивать (((
...
Рейтинг: 0 / 0
IoC. Постепенный перевод проекта. Возможно ли
    #38628883
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PavluhaТеперь вообще запутался, куда и как ее прикручивать (((

не-не..

Код: c#
1.
builder.RegisterType<ModelDataContextWrapper>().As<IModelDataContext>().InstancePerLifetimeScope();



и получайте где требуется IModelDataContext. незачем пилить свою собственную фабрику, если не планируется использовать её как точку расширения, или не используются дополнительные вариативные зависимости.
...
Рейтинг: 0 / 0
IoC. Постепенный перевод проекта. Возможно ли
    #38628888
Pavluha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
hVostt,

IModelDataContext не реализован, да и как его реализовать понятия не имею.
В EF как-то файл *.tt переписывали, а с dbml вообще непонятно или все не так понимаю?
...
Рейтинг: 0 / 0
IoC. Постепенный перевод проекта. Возможно ли
    #38628891
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PavluhaИх все в конструкторе указывать?

указывайте в конструкторе только те, которые реально используются. зачем все?

а SubmitChanges() я бы вынес отдельно:

Код: c#
1.
2.
3.
4.
5.
6.
    public interface IUnitOfWork
    {
        int Save();
        Task<int> SaveAsync();
        Task<int> SaveAsync(CancellationToken cancellationToken);
    }
...
Рейтинг: 0 / 0
IoC. Постепенный перевод проекта. Возможно ли
    #38628892
Pavluha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А если вот так сделать

Код: c#
1.
builder.RegisterType<ModelDataContextWrapper>().As<IDatabaseFactory>().InstancePerLifetimeScope();
...
Рейтинг: 0 / 0
IoC. Постепенный перевод проекта. Возможно ли
    #38628894
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PavluhaIModelDataContext не реализован, да и как его реализовать понятия не имею.

не обязательно интерфейс. можете класс зарегистрировать, без IModelDataContext.
...
Рейтинг: 0 / 0
IoC. Постепенный перевод проекта. Возможно ли
    #38628897
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PavluhaА если вот так сделать

Код: c#
1.
builder.RegisterType<ModelDataContextWrapper>().As<IDatabaseFactory>().InstancePerLifetimeScope();



да, можно и так. в зависимости от того, что вам от него нужно.
...
Рейтинг: 0 / 0
IoC. Постепенный перевод проекта. Возможно ли
    #38628898
Pavluha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
hVostt,

Нужен сам контекст
Код: c#
1.
2.
3.
4.
public ModelDataContextWrapper Get()
        {
            return _entityContext ?? (_entityContext = new ModelDataContextWrapper());
        }



Чтобы потом его убрать из DataManager и использовать, как вы описали
...
Рейтинг: 0 / 0
IoC. Постепенный перевод проекта. Возможно ли
    #38628902
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PavluhaА сам DataManager это менеджер репозиторий с lazy инициализацией.

Lazy-инициализация:

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
class Some {

   public Some(Lazy<IMyService> service)
   {
       _service = service;
   }

   public void Method()
   {
      _service.Value.ServiceMethod();  //  <----- вот здесь создаётся/извлекается экземпляр IMyService
   }
}
...
Рейтинг: 0 / 0
IoC. Постепенный перевод проекта. Возможно ли
    #38628906
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PavluhahVostt,

Нужен сам контекст
Код: c#
1.
2.
3.
4.
public ModelDataContextWrapper Get()
        {
            return _entityContext ?? (_entityContext = new ModelDataContextWrapper());
        }




Чтобы потом его убрать из DataManager и использовать, как вы описали

Код: c#
1.
builder.RegisterType<ModelDataContextWrapper>().InstancePerLifetimeScope();



если для ASP.NET MVC вы используете интеграцию Autofac.Mvc, то InstancePerLifetimeScope означает время жизни HttpContext.
...
Рейтинг: 0 / 0
IoC. Постепенный перевод проекта. Возможно ли
    #38628907
Pavluha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
hVostt,

Тогда получается все в конструкторе указывать, все репозитории?
...
Рейтинг: 0 / 0
IoC. Постепенный перевод проекта. Возможно ли
    #38628918
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PavluhahVostt,

Тогда получается все в конструкторе указывать, все репозитории?

все, которые нужны , если где-то нужны вообще все, значит что-то не так с архитектурой. но если их слишком много, тогда можно обойтись публичными попертями в Lazy-обёртке.
...
Рейтинг: 0 / 0
IoC. Постепенный перевод проекта. Возможно ли
    #38628921
Pavluha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Если я все правильно понял, то принцип такой:

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
 private static void ConfigureIoC()
        {
            var builder = new ContainerBuilder();
            builder.RegisterControllers(Assembly.GetExecutingAssembly());

            builder.RegisterType<ModelDataContextWrapper>().InstancePerLifetimeScope();
            builder.RegisterType<DataManager>().As<IDataManager>().InstancePerHttpRequest();
            builder.RegisterType<UserRepository>().As<IUserRepository>().InstancePerHttpRequest();

            IContainer container = builder.Build();
            DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); 
        }

        public class DataManager : IDataManager
	{		
                public DataManager(IUserRepository repository)
		{
                        _userRepository = repository;
		}

        private IUserRepository _userRepository;
 }

        public class UserController : Controller
	{
		private IDataManager _dataManager;

        public UserController(IDataManager DataManager)
		{
            _dataManager = DataManager;
		}
}
...
Рейтинг: 0 / 0
IoC. Постепенный перевод проекта. Возможно ли
    #38628933
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PavluhaЕсли я все правильно понял, то принцип такой:

да, всё верно, в этом и смысл
...
Рейтинг: 0 / 0
IoC. Постепенный перевод проекта. Возможно ли
    #38628943
Pavluha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
hVostt,

Тогда есть несколько вопрос по вашим
Вы сказали:
все, которые нужны, если где-то нужны вообще все, значит что-то не так с архитектурой. но если их слишком много, тогда можно обойтись публичными попертями в Lazy-обёртке.


Как тогда поступить с классом DataManager, если это класс есть простое хранилище всех репозиторий
И ссылка на него передается в фабрике:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
internal class ControllerFactory: DefaultControllerFactory
	{
		protected override IController GetControllerInstance(System.Web.Routing.RequestContext RequestContext, Type ControllerType)
		{
			if (ControllerType == null) return null;

			return Activator.CreateInstance(ControllerType, new DataManager()) as Controller;
		}
	}



Неправильная архитектура? Т.к. в конструкторе придется передавать все репозитории.
Где я ошибся? Явно что-то не так

Потому что в контроллере дальше идет такие вещи типа:
Код: c#
1.
			var users = _dataManager.Users.GetUsers((int)user.ProviderUserKey);
...
Рейтинг: 0 / 0
IoC. Постепенный перевод проекта. Возможно ли
    #38628967
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PavluhaКак тогда поступить с классом DataManager, если это класс есть простое хранилище всех репозиторий

у вас уже есть DI (который Autofac), который является хранилищем всех репозиторий. зачем вам ещё один, свой? единственный полезный метод SaveChanges стоит вынести в отдельный интерфейс типа IUnitOfWork, и использовать его там, где требуется сохранение информации.


PavluhaПотому что в контроллере дальше идет такие вещи типа:
Код: c#
1.
			var users = _dataManager.Users.GetUsers((int)user.ProviderUserKey);



если хотите работать в контроллере с пользователями, получайте в контроллере объект IUserRepository. в общем, получаейте те репозитории, которые вам в контроллере нужны.

если же у вас контроллер, которому нужны все репозитории, то наверное это не очень хороший контроллер, может его разделить на несколько?
...
Рейтинг: 0 / 0
IoC. Постепенный перевод проекта. Возможно ли
    #38629005
Pavluha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
hVostt,

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

И тогда класс DataManager вообще не нужен. (Есть контроллеры, в которых необходим доступ к др репозитории, что ограничивает фабрику контроллеров)
...
Рейтинг: 0 / 0
IoC. Постепенный перевод проекта. Возможно ли
    #38629014
Pavluha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Почему я ввязался в IoC. Стали возникать потребности в поддержке других СУБД, вот я и решил переписать DAL.
Т.е. таким способом, если возникнет вопрос о реализации поддержки другой СУБД, то достаточно написать другой DAL для той СУБД, а все остальное вообще не изменится.

Правильный ли данный подход или надо было не городить огород, а просто использовать абстрактную фабрику и все?
...
Рейтинг: 0 / 0
IoC. Постепенный перевод проекта. Возможно ли
    #38629032
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PavluhaНо тогда получается надо абстрагироваться от определенных репозиторий и передавать, например, IRepository, и уже в контроллере приводить его к типу IUserRepository.

этого точно делать не нужно.

но можно сделать так:

Код: c#
1.
2.
3.
            builder.RegisterGeneric(typeof(Repository<>))
                .As(typeof(IRepository<>))
                .InstancePerLifetimeScope();



Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
   public class UsersController : Controller
   {
      ...
      public UsersController(IRepository<User> userRepository)
      {
          _userRepository = userRepository;
      }
      ...
   }



PavluhaПравильный ли данный подход или надо было не городить огород, а просто использовать абстрактную фабрику и все?

можно и так, но думаю приведение типов -- не лучший вариант использования возможностей DI. тем более такого, как Autofac. этот зверь много чего умеет.
...
Рейтинг: 0 / 0
IoC. Постепенный перевод проекта. Возможно ли
    #38629066
Pavluha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
hVostt,


Немного запутался... (((

Как мне тогда работать с шаблоном фабрики

В данном случае все понятно
Код: c#
1.
2.
3.
4.
public Controller(IRepository<User> userRepository)
		{
            _dataManager = DataManager;
		}



но есть и такое:
Код: c#
1.
2.
3.
4.
public Controller(IRepository<User> userRepository, IRepository<Audit> auditRepository)
		{
            _dataManager = DataManager;
		}



Фабрика не работает в таком случае, массив надо передавать или переписывать и дублировать методы репозиторий
Самый простой вариант это дублировать методы репозиторий (Их не очень много)
...
Рейтинг: 0 / 0
IoC. Постепенный перевод проекта. Возможно ли
    #38629074
Pavluha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
И еще вопрос по поводу этого:

Код: c#
1.
return Activator.CreateInstance(ControllerType, new ADM.Monitoring.Models.DataManager()) as Controller;



На вход тогда пойдет IRepository<>?
...
Рейтинг: 0 / 0
IoC. Постепенный перевод проекта. Возможно ли
    #38629113
Pavluha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Нашел пример для фабрики
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
builder.Register(s => new ControllerFactory()).As<IControllerFactory>();

 public ControllerFactory()
        {
            List<IController> lstControllers = DependencyResolver.Current.GetServices<IController>().ToList();
            _controllerMap = new Dictionary<string, Func<RequestContext, IController>>();

            foreach (Controller contr in lstControllers)
            {
                string ctrName = contr.ControllerContext.RouteData.Values["Controller"].ToString();
                _controllerMap.Add(ctrName, c => contr);
            }
        }



Почему contr.ControllerContext = null
...
Рейтинг: 0 / 0
IoC. Постепенный перевод проекта. Возможно ли
    #38629130
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PavluhaФабрика не работает в таком случае, массив надо передавать или переписывать и дублировать методы репозиторий
Самый простой вариант это дублировать методы репозиторий (Их не очень много)

почему не работает?


PavluhaНашел пример для фабрики

если используете Autofac, то не надо реализовывать свою фабрику контроллеров:

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
protected void Application_Start()
{
    var builder = new ContainerBuilder();
    builder.RegisterControllers(typeof(MvcApplication).Assembly);
    var container = builder.Build();
    DependencyResolver.SetResolver(new AutofacDependencyResolver(container));

    // Other MVC setup...



вот и всё в принципе, что нужно :)
...
Рейтинг: 0 / 0
IoC. Постепенный перевод проекта. Возможно ли
    #38629165
Pavluha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
hVostt,

Видимо я уже не догоняю.

Как контроллер на входе получит тогда ModelContext?
Если мы ничего и нигде не указали
...
Рейтинг: 0 / 0
IoC. Постепенный перевод проекта. Возможно ли
    #38629172
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Pavluha,

почитай пожалуйста https://code.google.com/p/autofac/wiki/MvcIntegration

там всё написано про интеграцию Autofac в ASP.NET MVC. лишних телодвижений совершать не нужно. просто регистрируй свои сервисы, об остальном уже позаботились :)
...
Рейтинг: 0 / 0
IoC. Постепенный перевод проекта. Возможно ли
    #38629201
Pavluha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
hVostt,

Основную идею я понял, но это частный случай.
И если я все правильно понял и у меня 2 фабрики:

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
 if ()
            {
                ControllerBuilder.Current.SetControllerFactory(new ControllerFactory());
            }
            else
            {
                ControllerBuilder.Current.SetControllerFactory(new ErrorControllerFactory());
            }



и как вы пишите, что их не надо так добавлять
То тогда при конфигурировании я сам должен решить какая фабрика будет, а этим этого уже не решить
Код: c#
1.
builder.RegisterControllers(typeof(MvcApplication).Assembly);
...
Рейтинг: 0 / 0
IoC. Постепенный перевод проекта. Возможно ли
    #38629223
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PavluhaТо тогда при конфигурировании я сам должен решить какая фабрика будет, а этим этого уже не решить

блин, дак в этом и вся суть! в одном конкретном месте вы регистрируете нужные вам компоненты.

если поизучаете Autofac, то найдёте способы очень гибко конфигурировать создание объектов в момент их запроса на уровне регистрации компонентов.

сама возможность создавать фабрики контроллеров в MVC сделана для тестирования. никакого смысла создавать разные фабрики по какому-то условию нет. но и даже такой вариант использования можно провернуть в Autofac, не ковыряя фабрики.
...
Рейтинг: 0 / 0
IoC. Постепенный перевод проекта. Возможно ли
    #38630033
Pavluha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
hVostt,

Допустимо ли такое или это жесть:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
protected override IController GetControllerInstance(System.Web.Routing.RequestContext RequestContext, Type ControllerType)
{
	    if (ControllerType == null) return null;

	    var rd = RequestContext.RouteData;
	    string controller = rd.GetRequiredString("controller");
	    string actionName = rd.GetRequiredString("action");

            if (....) return null;
            if (....) return null;
            if (....) return null;

            List<String> list = new List<string>(new string[] { ...... });
            if (list.Contains(actionName) && ..................) return null;

            return Activator.CreateInstance(ControllerType, [color=red]DependencyResolver.Current.GetService<IDataManager>()[/color]) as Controller;
        }
...
Рейтинг: 0 / 0
IoC. Постепенный перевод проекта. Возможно ли
    #38630039
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PavluhaДопустимо ли такое или это жесть:

жесть :)

наверное стоит Activator.CreateInstance заменить на резолвинг с помощью DI.

а вообще, можно поинтересоваться, зачем вам понадобился свой GetControllerInstance? просто изучаете?
...
Рейтинг: 0 / 0
IoC. Постепенный перевод проекта. Возможно ли
    #38630046
Pavluha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
hVostt,

Есть 2 фабрики ControllerFactory, в зависимости от определенных условий, при старте системы подсовывается та или другая:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
 public static void Start() {
            ConfigureIoC();
 ViewEngines.Engines.Clear();
            if (.....)
            {
                ViewEngines.Engines.Add(new ThemedViewEngine());
                RouteConfig.RegisterRoutes(RouteTable.Routes);
                ControllerBuilder.Current.SetControllerFactory(new ControllerFactory());
            }
            else
            {
                ViewEngines.Engines.Add(new ErrorViewEngine());
                RouteConfig.RegisterCatchRoutes(RouteTable.Routes, message);
                ControllerBuilder.Current.SetControllerFactory(new ErrorControllerFactory());
            }
}

private static void ConfigureIoC()
        {
            var builder = new ContainerBuilder();
            builder.RegisterControllers(Assembly.GetExecutingAssembly());

            builder.RegisterType<ModelDataContext>().As<IModelDataContext>().InstancePerLifetimeScope();
            builder.RegisterType<ModelDataContextWrapper>().As<IModelDataContext>().InstancePerLifetimeScope();

            builder.RegisterType<DataManager>().As<IDataManager>().InstancePerHttpRequest();
            builder.RegisterType<AuditRepository>().As<IAuditRepository>().InstancePerHttpRequest();
            builder.RegisterType<CommandRepository>().As<ICommandRepository>().InstancePerHttpRequest();
            builder.RegisterType<CDMRepository>().As<ICDMRepository>().InstancePerHttpRequest();
            builder.RegisterType<MonitoringRepository>().As<IMonitoringRepository>().InstancePerHttpRequest();
            builder.RegisterType<RoleRepository>().As<IRoleRepository>().InstancePerHttpRequest();
            builder.RegisterType<SettingRepository>().As<ISettingRepository>().InstancePerHttpRequest();
            builder.RegisterType<UserRepository>().As<IUserRepository>().InstancePerHttpRequest();


            builder.RegisterFilterProvider();

            IContainer container = builder.Build();
            DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); 
        }
...
Рейтинг: 0 / 0
IoC. Постепенный перевод проекта. Возможно ли
    #38630110
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PavluhaЕсть 2 фабрики ControllerFactory, в зависимости от определенных условий, при старте системы подсовывается та или другая:

было бы конечно очень любопытно узнать для чего это всё. какие условия.

и да, в зависимости от этих условий можно регистрировать разные фабрики в DI.
...
Рейтинг: 0 / 0
IoC. Постепенный перевод проекта. Возможно ли
    #38630156
Pavluha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
hVosttбыло бы конечно очень любопытно узнать для чего это всё. какие условия.


В зависимости от списка доступных модулей подключается или нет та или иная фабрика контроллеров


hVosttи да, в зависимости от этих условий можно регистрировать разные фабрики в DI.

А можно пример? Просто отказаться от них пока нет возможности, в них есть доп проверки на доступность тех или иных контроллеров от установленных настроек в системе
...
Рейтинг: 0 / 0
IoC. Постепенный перевод проекта. Возможно ли
    #38630163
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PavluhaА можно пример?

Вот здесь подробненько
...
Рейтинг: 0 / 0
IoC. Постепенный перевод проекта. Возможно ли
    #38634782
Евгений З
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Все беды из-за того что не должно быть некого всеобъемлющего DataManager'а, сборной солянки из всех репозиториев. Обычная практика - создавать типы, отвечающие за определенный род деятельности и предоставляющие необходимое API. Например UserManager или UserService, который будет оперировать IUserRepository и IAuditRepository. Дальше к примеру операция создания юзера должна дернуть юзер репозиторий и записать это событие в аудит журнал. Все зависимости инжектить через конструктор без всяких там паблик свойств, т.е. юзер менеджер не должен давать доступ к своим репозиториям, он должен лишь иметь методы типа CreateUser, LoadUsers и т.д. Почитай про onion architecture, например тут http://www.develop.com/onionarchitecture
...
Рейтинг: 0 / 0
IoC. Постепенный перевод проекта. Возможно ли
    #38634795
Евгений З
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
PavluhahVostt,


Немного запутался... (((

Как мне тогда работать с шаблоном фабрики

В данном случае все понятно
Код: c#
1.
2.
3.
4.
public Controller(IRepository<User> userRepository)
		{
            _dataManager = DataManager;
		}



но есть и такое:
Код: c#
1.
2.
3.
4.
public Controller(IRepository<User> userRepository, IRepository<Audit> auditRepository)
		{
            _dataManager = DataManager;
		}



Фабрика не работает в таком случае, массив надо передавать или переписывать и дублировать методы репозиторий
Самый простой вариант это дублировать методы репозиторий (Их не очень много)

Контроллер не должен оперировать репозиториями. Репозиторий должен тупо выполнять CRUD операции надо определенным типом сущности. Дальше должен быть сервис или менеджер типа UserService, который дергает нужные ему репозитории и содержит бизнес логику, транзакционные методы, батч операции и т.д.
...
Рейтинг: 0 / 0
IoC. Постепенный перевод проекта. Возможно ли
    #38634824
Pavluha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Евгений З,

А он и не оперирует у меня сейчас.
Каждый контроллер получает на входе IDatamanager.
IDataManager имеет доступ к I....Repository, которая в свою очередь уже работает с данными.
...
Рейтинг: 0 / 0
IoC. Постепенный перевод проекта. Возможно ли
    #38635342
Pavluha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Подскажите, как лучше сделать "инъекцию" в UserProvider

Сейчас все выглядит так:

Код: c#
1.
2.
3.
internal class UserProvider : MembershipProvider
    {
        public IUserRepository Users { get; set; }




Как теперь настроить builder?
...
Рейтинг: 0 / 0
IoC. Постепенный перевод проекта. Возможно ли
    #38635358
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Pavluha
Код: c#
1.
MembershipProvider



зачем оно вам? мсу наслушались?
...
Рейтинг: 0 / 0
IoC. Постепенный перевод проекта. Возможно ли
    #38635372
Pavluha
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
hVostt,

У меня form-аутентификация с разными плюшками, поэтому и реализовал провайдер пользователей и ролей тоже. МСУ тут ни при чем

Я вроде решил проблему таким способом:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
            builder.Register(context => Membership.Provider).ExternallyOwned();
            builder.Register(context => Roles.Provider).ExternallyOwned();
            builder.RegisterType<UserProvider>();

            builder.RegisterFilterProvider();

            IContainer container = builder.Build();
            DependencyResolver.SetResolver(new AutofacDependencyResolver(container));

            var lifetimeScope = DependencyResolver.Current.GetService<ILifetimeScope>();
            lifetimeScope.InjectProperties(Membership.Provider);
            lifetimeScope.InjectProperties(Roles.Provider);
...
Рейтинг: 0 / 0
IoC. Постепенный перевод проекта. Возможно ли
    #38635383
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Pavluha,

ну можно так, с помощью ExternallyOwned
...
Рейтинг: 0 / 0
47 сообщений из 47, показаны все 2 страниц
Форумы / ASP.NET [игнор отключен] [закрыт для гостей] / IoC. Постепенный перевод проекта. Возможно ли
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]