StructureMap认为它必须注入构造函数并抛出异常

ahm*_*iee 1 c# structuremap asp.net asp.net-mvc structuremap3

我在我的应用程序中使用了StructureMap和ASP.Net Identity.我有这条线的时候Application_Start

ControllerBuilder.Current.SetControllerFactory(new StructureMapControllerFactory());
Run Code Online (Sandbox Code Playgroud)

这是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;
    }
}
Run Code Online (Sandbox Code Playgroud)

return ObjectFactory.GetInstance(controllerType) as Controller;抛出StructureMapConfigurationException异常说:

No default Instance is registered and cannot be automatically determined for type 'IUserStore<Person>'
Run Code Online (Sandbox Code Playgroud)

但如果我删除ControllerBuilder.Current.SetControllerFactory(new StructureMapControllerFactory());行一切正常,所以它的StructureMap的问题不是我的代码.

Ric*_*Net 5

我认为例外情况很明显.它可能来自Identity模板的AccountController,它带有2个构造函数.

StructureMap 默认使用最贪婪的构造函数.该模板带有2个构造函数,一个默认构造函数和一个带ApplicationUserManager对象的构造函数.

如果没有StructureMap,则调用默认构造函数,并使用服务定位器反模式解析ApplicationUserManager .

StructureMap现在必须创建ApplicationUserManager,因为这是一个具体类型,它将尝试.如果它是一个抽象,它将在那里抛出异常.该ApplicationUserManager但是具有需要一个单一的构造IUserStore<Person>.因为这是一个抽象而容器没有此类型的注册,所以StructureMap无法为您创建类型.

要解决此问题,您应该删除默认构造函数并注册ApplicationUserManager和依赖服务,这些服务至少是实现IUserStore的某个组件.

编辑: 虽然您在评论中提到的解决方案可能有效,但由于以下原因,这不是更好的解决方案:

  1. 拥有多个构造函数是一种反模式
  2. 您现在正在使用的服务定位器反模式解决了ApplicationUserManagerHttpContext

VS2013附带的模板需要一些工作才能使用依赖注入.这将耗费一些时间.好消息是,这是可能的,可行的,将大大提高你的知识Owin,Asp.Net Identity依赖注入和坚实的设计.

有几个关于如何开始重构模板以使用依赖注入的博客.你可以在这里这里阅读