StructureMap считает, что он должен внедрить конструктор и выдает исключение
Я использую StructureMap и ASP.Net Identity в своем приложении. Когда у меня есть эта строка в моем Application_Start
ControllerBuilder.Current.SetControllerFactory(new StructureMapControllerFactory());
а это StructureMapControllerFactory
:
public class StructureMapControllerFactory : DefaultControllerFactory
{
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
if (controllerType == null && requestContext.HttpContext.Request.Url != null)
throw new InvalidOperationException(string.Format("Page not found: {0}",
requestContext.HttpContext.Request.Url.AbsoluteUri.ToString(CultureInfo.InvariantCulture)));
return ObjectFactory.GetInstance(controllerType) as Controller;
}
}
return ObjectFactory.GetInstance(controllerType) as Controller;
бросает StructureMapConfigurationException
исключение говорит:
No default Instance is registered and cannot be automatically determined for type 'IUserStore<Person>'
но если я уберу ControllerBuilder.Current.SetControllerFactory(new StructureMapControllerFactory());
Строка все идет хорошо, так что это проблема StructureMap, а не мой код.
1 ответ
Я думаю, что исключение очевидно. Вероятно, речь идет об AccountController из шаблона Identity, который поставляется с двумя конструкторами.
StructureMap будет использовать самый жадный конструктор по умолчанию. Шаблон поставляется с 2 конструкторами, один конструктор по умолчанию и один конструктор с ApplicationUserManager
объект.
Без StructureMap вызывается конструктор по умолчанию, и ApplicationUserManager будет разрешен с использованием антишаблона локатора службы.
StructureMap теперь должен создать ApplicationUserManager
и потому что это конкретный тип, он попробует. Если это был абстракция, то тут же возникнет исключение. ApplicationUserManager
Однако есть один конструктор, который нуждается в IUserStore<Person>
, Поскольку это абстракция и контейнер не имеет регистрации этого типа, StructureMap не может создать тип для вас.
Чтобы решить эту проблему, вы должны удалить конструктор по умолчанию и зарегистрировать ApplicationUserManager и зависящие от него сервисы, которые являются, по крайней мере, некоторым компонентом, реализующим IUserStore.
Изменить: Хотя решение, которое вы упомянули в комментариях, может работать, это не является предпочтительным решением из-за:
- Наличие нескольких конструкторов является анти-паттерном
- Теперь вы используете анти-шаблон сервисного локатора для разрешения
ApplicationUserManager
отHttpContext
Шаблоны, поставляемые с VS2013, нуждаются в некоторой работе для использования с внедрением зависимостей. Это будет стоить времени. Хорошей новостью является то, что это возможно и выполнимо и значительно улучшит ваши знания Owin
, Asp.Net Identity
, Внедрение зависимостей и ТВЕРДЫЙ дизайн.
Есть несколько блогов о том, как начать рефакторинг шаблонов для работы с внедрением зависимостей. Вы можете прочитать об этом здесь и здесь