Я использую MVC3, Entity Framework v4.3 Code First и SimpleInjector. У меня есть несколько простых классов, которые выглядят так:
public class SomeThing
{
public int Id { get; set; }
public string Name { get; set; }
}
У меня есть еще один объект, который выглядит так:
public class MainClass
{
public int Id { get; set; }
public string Name { get; set; }
public virtual AThing AThingy { get; set; }
public virtual BThing BThingy { get; set; }
public virtual CThing CThingy { get; set; }
public virtual DThing DThingy { get; set; }
public virtual EThing EThingy { get; set; }
}
Каждая вещь (в настоящее время) имеет свой собственный класс менеджера, например:
public class SomeThingManager
{
private readonly IMyRepository<SomeThing> MyRepository;
public SomeThingManager(IMyRepository<SomeThing> myRepository)
{
MyRepository = myRepository;
}
}
Следовательно, мой MainController выглядит следующим образом:
public class MainController
{
private readonly IMainManager MainManager;
private readonly IAThingManager AThingManager;
private readonly IBThingManager BThingManager;
private readonly ICThingManager CThingManager;
private readonly IDThingManager DThingManager;
private readonly IEThingManager EThingManager;
public MainController(IMainManager mainManager, IAThingManager aThingManager, IBThingManager bThingManager, ICThingManager cThingManager, IDThingManager dThingManager, IEThingManager eThingManager)
{
MainManager = mainManager;
AThingManager = aThingManager;
BThingManager = bThingManager;
CThingManager = cThingManager;
DThingManager = dThingManager;
EThingManager = eThingManager;
}
...various ActionMethods...
}
На самом деле в этом контроллере внедренных зависимостей в два раза больше. Это пахнет. Запах еще хуже, когда вы также знаете, что существует OtherController со всеми или большинством таких же зависимостей. Я хочу провести рефакторинг.
Я уже достаточно знаю о внедрении зависимостей, чтобы понять, что внедрение свойств и поиск сервисов — плохие идеи.
Я не могу разделить свой MainController, потому что это один экран, который требует, чтобы все эти вещи отображались и редактировались одним нажатием одной кнопки «Сохранить». Другими словами, один метод действия с публикацией сохраняет все (хотя я готов изменить это, если это имеет смысл, если это все еще одна кнопка «Сохранить»). Этот экран создан с помощью Knockoutjs и сохраняется с сообщениями Ajax, если это имеет значение.
Я с юмором использовал Ambient Context, но я не уверен, что это правильный путь. Я также с юмором использовал внедрение Фасада. Мне также интересно, следует ли мне реализовать командную архитектуру на этом этапе. (Разве все вышеперечисленное не просто перемещает запах куда-то еще?)
Наконец, и, возможно, независимо от трех вышеперечисленных подходов, следует ли вместо этого иметь один, скажем, LookupManager с явными методами, такими как GetAThings(), GetAThing(id), GetBThings(), GetBThing(id) и т. д.? (Но тогда в этот LookupManager потребуется несколько встроенных репозиториев или репозиторий нового типа.)
Мои размышления в сторону, мой вопрос, чтобы повторить: каков хороший способ рефакторинга этого кода, чтобы уменьшить сумасшедшее количество внедряемых зависимостей?