I cannot get StructureMap to inject a value into the constructor of the MvcApplication of the Global.asax.cs file. I have created a brand new and clean project and used StructureMap.MVC5 package to generate the necessary structures inside the DependencyResolution subfolder.
My class to be injected is simple:
namespace SMTest.Models {
public interface ITestSM
{
int OnePlusTwo();
}
public class TestSM : ITestSM
{
public int OnePlusTwo()
{
return 1 + 2;
}
} }
IoC.cs is:
namespace SMTest.DependencyResolution {
using StructureMap;
public static class IoC {
public static IContainer Initialize() {
return new Container(c => c.AddRegistry<DefaultRegistry>());
}
}
}
StructuremapMvc.cs contains:
public static void Start() {
IContainer container = IoC.Initialize();
StructureMapDependencyScope = new StructureMapDependencyScope(container);
DependencyResolver.SetResolver(StructureMapDependencyScope);
DynamicModuleUtility.RegisterModule(typeof(StructureMapScopeModule));
}
And DefaultRegistry.cs contains:
public DefaultRegistry() {
Scan(
scan => {
scan.TheCallingAssembly();
scan.WithDefaultConventions();
scan.With(new ControllerConvention());
});
For<ITestSM>().Singleton().Use<TestSM>();
}
I can easily inject it into the HomeController:
public class HomeController : Controller
{
private ITestSM _testsm;
public HomeController(ITestSM testsm):base()
{
_testsm = testsm;
}
public ActionResult Index()
{
return View();
}
But when I try to do that in Global.asax.cs:
public class MvcApplication : System.Web.HttpApplication
{
private ITestSM _testsm;
public MvcApplication(ITestSM testsm)
{
_testsm = testsm;
}
protected void Application_Start()
{...
I get the error: Compiler Error Message: CS7036: There is no argument given that corresponds to the required formal parameter 'testsm' of 'MvcApplication.MvcApplication(ITestSM)'
Despite the fact that IoC init triggers before the Application_Start, StructuremapMvc.cs:
[assembly: PreApplicationStartMethod(typeof(StructuremapMvc), "Start")]
[assembly: ApplicationShutdownMethod(typeof(StructuremapMvc), "End")]
Any idea?
Edit: I was able to inject it into Global.asax.cs explicitly:
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();
}
}
However, the session I get here is not the one injected into the controller so I am flushing and closing the wrong one, leaving data not commited to the DB.