2012-09-05 77 views
5

控制器中的对象在运行时未被注入。使用Spring .NET向MVC控制器注入依赖项

Web.config文件:

<sectionGroup name="spring"> 
     <section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core" /> 
     <section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core" /> 
    </sectionGroup> 

。 。 。

<!-- Spring Context Configuration --> 
<spring> 
    <context> 
     <resource uri="config://spring/objects"/> 
    </context> 
    <objects configSource="App_Config\Spring.config" /> 
</spring> 
<!-- End Spring Context Configuration --> 

Spring.config:

<?xml version="1.0" encoding="utf-8" ?> 
<objects xmlns="http://www.springframework.net"> 

    <!-- Crest is the WCF service to be exposed to the client, could not use a singleton --> 

    <object id="TestController" type="Project.Controllers.TestController, Project" singleton="false"> 
     <property name="ObjectA" ref="ObjectImpl"/> 
    </object> 

    <object id="ObjectImpl" type="Project.Code.Implementations.ClassA, Project" singleton="false" /> 

</objects> 

的TestController:

public class TestController: Controller 
    { 
     // this object will be injected by Spring.net at run time 
     private ClassA ObjectA { get; set; } 

问题:

在运行时,对象A没有得到注入,并保持空,这 原因整个代码中的空例外。

替代方法: 我可以手动初始化Spring对象并使用下面的代码获取它的对象。

 var ctx = ContextRegistry.GetContext(); 
     var objectA = ((IObjectFactory)ctx).GetObject("ObjectImpl") as ClassA; 
+1

你错过了一些难题。请看看[这里](http://foldingair.blogspot.hu/2010/01/springnet-and-aspmvc-getting-started.html)和[这里](http://www.springframework.net /doc-latest/reference/html/web-mvc.html)和[这里](http://nuget.org/packages/Spring.Web.Mvc/1.3.2)。 – nemesv

+0

@nemesv是的,你是正确的,事实证明我错过了一块拼图。谢谢! –

回答

3

事实证明,我错过了MVC的Spring实现中非常重要的一部分。

我对该问题的解决方案是通过添加实现IDependencyResolver的DependencyResolver。

DependencyResolver:

public class SpringDependencyResolver : IDependencyResolver 
{ 
    private readonly IApplicationContext _context; 

    public SpringDependencyResolver(IApplicationContext context) 
    { 
     _context = context; 
    } 

    public object GetService(Type serviceType) 
    { 
     var dictionary = _context.GetObjectsOfType(serviceType).GetEnumerator(); 

     dictionary.MoveNext(); 
     try 
     { 
      return dictionary.Value; 
     } 
     catch (InvalidOperationException) 
     { 
      return null; 
     } 
    } 

    public IEnumerable<object> GetServices(Type serviceType) 
    { 
      return _context.GetObjectsOfType(serviceType).Cast<object>(); 
    } 
} 

的Global.asax.cs:

protected void Application_Start() 
    { 
     AreaRegistration.RegisterAllAreas(); 

     FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 
     RouteConfig.RegisterRoutes(RouteTable.Routes); 

     DependencyResolver.SetResolver(new SpringDependencyResolver(ContextRegistry.GetContext())); 
    } 
+0

这将不起作用,因为上下文在创建中,而ContextRegistry.GetContext()会抛出异常! – Tobias

1

您可以实现自己的IDependencyResolver,就像你在你的答案建议。但是请注意,自(iirc)版本1.3.1以来,Spring.NET已经内置了对asp.net mvc 2.03.0的支持。 Spring.net 2.0(pre release available on NuGet)也支持4.0版本。考虑改用这些库。

您可能有兴趣比较您的SpringDependencyResolverthe one provided by the Spring.net team

+0

感谢@Marijn的建议。你对Spring.NET内置的支持是正确的。但在我们的例子中,问题在于我们正在使用MVC4框架,而Spring.net 2.0尚未准备好发布。因此,自定义实施更适合我们的情况。我将看看DependencyResolver [由Spring提供](https://fisheye.springsource.org/browse/spring-net/src/Spring/Spring.Web.Mvc4/SpringMvcDependencyResolver.cs?hb=true),谢谢! –

+0

我试图使用Spring提供的依赖解析器,但在我的Global.asax(方法init,继承自MvcApplication)“DependencyResolver。SetResolver(新的SpringDependencyResolver(ContextRegistry.GetContext()));“抛出错误说上下文仍在创建中。 –