2016-10-30 40 views
0

我不确定我的期望是否错误。我正在使用ASP.NET MVC(不是核心)和Autofac。我有我的网站的每一页上显示的图像,我创建了一个服务返回一个随机图像的名字,像这样ASP.NET Autofac Singleton运行两次构造函数注入

接口

public interface IBreadCrumbImage 
{ 
    string GetImage(); 
} 

CLASS(剪断,为了简洁)

public class BreadCrumbImage : IBreadCrumbImage 
{ 
    public string GetImage() 
    { 
     return ImageUrl; 
    } 
} 

的global.asax.cs(Autofac注册)

protected void Application_Start() 
{ 
     var builder = new ContainerBuilder(); 
     builder.RegisterControllers(typeof(MvcApplication).Assembly); 
     builder.RegisterType<BreadCrumbImage>().As<IBreadCrumbImage>().SingleInstance(); 
     var container = builder.Build(); 
     DependencyResolver.SetResolver(new AutofacDependencyResolver(container)); 
} 

CONTROLLER

public class HomeController : Controller 
{ 
    private IBreadCrumbImage _breadCrumbImage; 

    public ActionResult Index(BreadCrumbImage breadCrumbImage) 
    { 
     _breadCrumbImage = breadCrumbImage; 
     var x = _breadCrumbImage.GetImage(); 
     ViewBag.BreadCrumbImage = "/img/BreadCrumbs/" + x; 
     return View(); 
    } 
} 

所有这些工作,我得到我的IMAGE随机显示..但是,设置断点,这个BreadCrumbImage服务被实例化每次访问。我想要实例化一次(图像的加载是在BreadCrumbImage的构造函数中完成的,它读取文件并将它们放入数组中 - 在启动应用程序时不需要这样做,并且GetImages只是从数组中获取rnd)。

我在SingleInstance中注册了这个错误,还是因为我期待它而不工作,我将不得不拥有一些与Global.asax中创建的生成器绑定的基本解析器。 CS?

更新:答案,谢谢特拉维斯。需要将其加入到autofac配置中,并且所有工作都像魅力一样。

builder.RegisterType<ExtensibleActionInvoker>() 
     .As<IActionInvoker>() 
     .WithParameter("injectActionMethodParameters", true); 

回答

2

看着你提供的控制器,你没有使用构造函数注入。Index方法是一个动作方法,而不是构造函数。此外,它要求BreadCrumbImage而不是IBreadCrumbImage

如果从断点看看调用堆栈,我猜你会看到MVC模型绑定正在实例化BreadCrumbImage,而不是Autofac。我没有看到Autofac设置中的任何地方使用action parameter injection机制,并且如果您仍然看到MVC模型绑定在调用堆栈中,因为您没有将BreadCrumbImage注册为自己 - 您将其注册为IBreadCrumbImage所以这是Autofac将解决它的唯一一件事。使用您显示的注册,您将无法通过容器解析具体的BreadCrumbImage

+0

你是我的英雄。更新我缺少的问题,是的,你是正确的,MVC做了所有的工作,而不是Autofac。这也回答了我的另一个开放问题。真的非常感谢你! – plankalkul

+0

你应该关闭你的另一个问题,所以大家不要试图继续回答。 –