我无法让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();
}
}
但是,我在这里得到的会话不是注入控制器的会话,因此我正在刷新并关闭错误的会话,而不会将数据提交给数据库。
答案 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()
方法中配置。