Asp.net mvc 在扩展方法中使用IoC

Asp.net mvc 在扩展方法中使用IoC,asp.net-mvc,ioc-container,structuremap,Asp.net Mvc,Ioc Container,Structuremap,我正在开发一个ASP MVC 3应用程序,我正在编写一个自定义html帮助程序。它并没有什么特别或非常复杂的地方,但它需要一个来自结构映射的接口实例。我知道我可以简单地从方法内部调用structuremaps的对象工厂,但是由于应用程序的其余部分使用IoC而不是服务位置,所以我希望保持这种方式 是否有一种方法可以从内部和asp net mvc应用程序将接口注入扩展方法 更新 我正在做的一个例子可能会有所帮助: public static class ShowUrl { public st

我正在开发一个ASP MVC 3应用程序,我正在编写一个自定义html帮助程序。它并没有什么特别或非常复杂的地方,但它需要一个来自结构映射的接口实例。我知道我可以简单地从方法内部调用structuremaps的对象工厂,但是由于应用程序的其余部分使用IoC而不是服务位置,所以我希望保持这种方式

是否有一种方法可以从内部和asp net mvc应用程序将接口注入扩展方法

更新

我正在做的一个例子可能会有所帮助:

public static class ShowUrl
{
    public static string ForShow(this UrlHelper url, int showId)
    {
        var service = ObjectFactory.GetInstance<IPerformanceService>();

        var showName = service.GetPerformanceTitle(showId);

        return url.Action(MVC.Performance.Details(showId, showName.ToFriendlyUrl()));
    }
}
公共静态类ShowUrl
{
显示的公共静态字符串(此UrlHelper url,int showId)
{
var service=ObjectFactory.GetInstance();
var showName=service.GetPerformanceTitle(showId);
返回url.Action(MVC.Performance.Details(showId、showName.ToFriendlyUrl());
}
}
它是这样使用的:

<a href='<%= Url.ForShow(1)%>'>


本质上,我正试图用一个实体id构建一个带有slug的URL。也许我只是用一种非常愚蠢的方式来实现这一点

我不建议这样做。扩展方法通常最好直接用于类型上的简单、众所周知的操作。如果您的扩展方法依赖于拥有另一种类型的实例,那么它很可能不应该是一个扩展方法

考虑创建一个执行此功能的实际服务类,并将其注入到需要的地方。如果你真的需要一个扩展方法,考虑打包你的扩展方法在另一个静态类/方法中需要的功能,并且避免使用任何类型的注入或位置。
共享一些代码可能会更清楚地了解您的具体情况。

无法将依赖项注入扩展方法


对于ASP.NET MVC助手,您将不得不进行某种服务定位—是否使用某种抽象将其掩埋取决于您。

您不应该在扩展方法中直接调用structuremap。此外,您还应创建一个可测试版本,该版本采用IPerformanceService参数,如下所示:

public static class ShowUrl
{
    public static string ForShow(this UrlHelper url, int showId)
    {
        //Use the MVC DependencyResolver NOT Structuremap directly (DependencyResolver is using structuremap)
        return url.ForShow(showId, DependencyResolver.Current.GetService<IPerformanceService>())
    }

    //For Unit Testing
    public static string ForShow(this UrlHelper url, int showId, IPerformanceService performanceService)
    {
        var showName = performanceService.GetPerformanceTitle(showId);
        return url.Action(MVC.Performance.Details(showId, showName.ToFriendlyUrl()));
    }
}

有关模拟UrlHelper的更多信息:

是否使用MVC DependencyResolver?您可以将依赖项注入扩展方法,只需将依赖项作为方法参数传入(方法注入)。然而,这并不是很方便,尤其是当您需要传递多个依赖项时。我最初包含了一些演示代码来精确地显示这一点,但我意识到最终的结果并不是更漂亮。
Assert.Equal("TheUrl", url.ForShow(8, new PerformanceService());