4

我试图让结构图正确创建我的控制器,我正在使用 DI 将 INewsService 注入到 NewsController 中,这是我唯一的构造函数。

public class NewsController : Controller
{
    private readonly INewsService newsService;

    public NewsController(INewsService newsService)
    {
        this.newsService = newsService;
    }

    public ActionResult List()
    {
        var newsArticles = newsService.GetNews();
        return View(newsArticles);
    }
}

我正在使用此代码启动应用程序

public class Application : HttpApplication
{
    protected void Application_Start()
    {
        RegisterIoC();
        RegisterViewEngine(ViewEngines.Engines);
        RegisterRoutes(RouteTable.Routes);
    }

    public static void RegisterIoC()
    {
        ObjectFactory.Initialize(config => {
            config.UseDefaultStructureMapConfigFile = false;
            config.AddRegistry<PersistenceRegistry>();
            config.AddRegistry<DomainRegistry>();
            config.AddRegistry<ControllerRegistry>();
        });
        DependencyResolver.InitializeWith(new StructureMapDependencyResolver());
        ControllerBuilder.Current.SetControllerFactory(typeof(IoCControllerFactory));            
    }
}

但是 Structuremap 似乎不想注入 INewsService 并且我收到错误 No parameterless constructor defined for this object。

我错过了什么?

4

3 回答 3

6

我使用 StructureMap 提供的“默认约定”机制来避免需要单独配置每个接口。下面是我用来完成这项工作的代码:

我的 Global.asax 在 Application_Start 中有这一行(它使用来自 MvcContrib 的 StructureMap 工厂):

protected void Application_Start()
{
    RegisterRoutes(RouteTable.Routes);
    ObjectFactory.Initialize(x =>
    {
        x.AddRegistry(new RepositoryRegistry());
    });
    ControllerBuilder.Current.SetControllerFactory(typeof(StructureMapControllerFactory));
}

RepositoryRegistry 类如下所示:

public class RepositoryRegistry : Registry
{

    public RepositoryRegistry()
    {
        Scan(x =>
        {
            x.Assembly("MyAssemblyName");
            x.With<DefaultConventionScanner>();
        });

    }

}

DefaultConventionScanner 查找遵循 ISomethingOrOther 和 SomethingOrOther 命名约定的接口/类对,并自动将后者关联为前一个接口的具体类型。

如果您不想使用该默认约定机制,则可以在 Registry 类中添加代码,以使用以下语法将每个接口显式映射到具体类型:

ForRequestedType<ISomethingOrOther>().TheDefaultIsConcreteType<SomethingOrOther>();
于 2009-02-28T00:19:37.417 回答
0

除非我遗漏了什么,否则您不会告诉 StructureMap 用于 INewsService 的具体类型。您需要添加以下内容:

TheConcreteTypeOf<INewsService>.Is<MyConcreteNewsService>();

我不知道我脑海中的确切语法,但这就是你所缺少的。一旦你指定了它,它就会知道要注入控制器的 INewsService 的哪个实例。

于 2009-02-27T15:23:58.187 回答
0

ASP.NET MVC 当前使用默认的无参数构造函数来实例化控制器,这排除了任何基于构造函数的依赖注入。为此,您确实需要使用MvcContrib项目,该项目具有对 StructureMap(和 Castle/Spring.NET/Unity)的内置支持,尽管当前文档不存在(从字面上看,您会得到一个存根 wiki 页面,不是一个好兆头)。Erv Walter 在此线程中的代码示例展示了如何设置 StructureMap 集成。

于 2009-05-06T04:18:12.633 回答