Application_Start

时间:2016-03-02 12:39:06

标签: asp.net-mvc-5 structuremap3

我无法让StructureMap将值注入Global.asax.cs文件的MvcApplication的构造函数中。我创建了一个全新的干净项目,并使用StructureMap.MVC5包在DependencyResolution子文件夹中生成必要的结构。

我要注射的课很简单:

namespace SMTest.Models {
    public interface ITestSM
    {
        int OnePlusTwo();
    }
    public class TestSM : ITestSM
    {
        public int OnePlusTwo()
        {
            return 1 + 2;
        }
    } }

IoC.cs是:

namespace SMTest.DependencyResolution {
    using StructureMap;

    public static class IoC {
        public static IContainer Initialize() {
            return new Container(c => c.AddRegistry<DefaultRegistry>());
        }
    }
}

StructuremapMvc.cs包含:

    public static void Start() {
        IContainer container = IoC.Initialize();
        StructureMapDependencyScope = new StructureMapDependencyScope(container);
        DependencyResolver.SetResolver(StructureMapDependencyScope);
        DynamicModuleUtility.RegisterModule(typeof(StructureMapScopeModule));
    }

DefaultRegistry.cs包含:

    public DefaultRegistry() {
        Scan(
            scan => {
                scan.TheCallingAssembly();
                scan.WithDefaultConventions();
                scan.With(new ControllerConvention());
            });

        For<ITestSM>().Singleton().Use<TestSM>();
    }

我可以轻松地将它注入HomeController:

public class HomeController : Controller
{
    private ITestSM _testsm;
    public HomeController(ITestSM testsm):base()
    {
        _testsm = testsm; 
    }

    public ActionResult Index()
    {
        return View();
    }

但是当我尝试在Global.asax.cs中执行此操作时:

public class MvcApplication : System.Web.HttpApplication
{
    private ITestSM _testsm;
    public MvcApplication(ITestSM testsm)
    {
        _testsm = testsm;
    }

    protected void Application_Start()
    {...

我收到错误: 编译器错误消息:CS7036:没有给出对应于所需形式参数的参数&#39; testsm&#39; &#39; MvcApplication.MvcApplication(ITestSM)&#39;

尽管IoC init在Application_Start,StructuremapMvc.cs之前触发了事实:

[assembly: PreApplicationStartMethod(typeof(StructuremapMvc), "Start")]
[assembly: ApplicationShutdownMethod(typeof(StructuremapMvc), "End")]

有什么想法吗?

修改 我能够明确地将它注入Global.asax.cs:

    protected void Application_EndRequest(object sender, System.EventArgs e)
    {
        if (!this.Request.Path.Contains("Content") && !this.Request.Path.Contains("Scripts") && !this.Request.Path.Contains("less"))
        {
            ISession currentSession = SMTest.App_StartStructuremapMvc.StructureMapDependencyScope.Container.GetInstance<ISession>();
            currentSession.Flush();
            currentSession.Close();
        }
    }

但是,我在这里得到的会话不是注入控制器的会话,因此我正在刷新并关闭错误的会话,而不会将数据提交给数据库。

1 个答案:

答案 0 :(得分:5)

不幸的是,不可能通过构造函数注入将依赖项注入到MvcApplication类中。执行此操作的唯一方法是,您已经发现,通过其静态实例(也称为服务定位器模式)访问容器。

让我解释一下为什么会出现这种情况。

设置容器后,请调用以下行: DependencyResolver.SetResolver(StructureMapDependencyScope);

此行设置将IoC容器(在此实例中为StructureMap)挂钩到ASP.NET MVC的依赖项解析器。最终充当ASP.NET和StructureMap容器​​之间的接口。

当MVC框架实例化控制器时,将通过DependencyResolver中配置的实例解析依赖关系。但是,在创建MvcApplication实例时,不会通过DependencyResolver实例解析依赖关系。通过DependencyResolver解析依赖关系的唯一实例类型是控制器。最终,这是ASP.NET MVC框架中的一个缺陷(已在ASP.NET Core MVC中得到纠正)。

除此之外,在调用构造函数时甚至不配置容器,并且仅在调用控制器后调用的Start()方法中配置。