使用 Spring .NET 将依赖项注入 MVC 控制器



控制器中的对象在运行时未被注入。

网络配置:

    <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_ConfigSpring.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>

测试控制器:

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

问题:

在运行时,ObjectA 不会被注入并保持空,这 导致整个代码出现空异常。

另类:我可以使用以下代码手动初始化 Spring 对象并获取其对象。

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

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

我对这个问题的解决方案是添加一个实现 IDependencyResolver 的依赖解析器。

依赖关系解析器:

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()));
    }

您可以实现自己的IDependencyResolver,就像您在答案中建议的那样。但请注意,自 (iirc( 版本 1.3.1 以来,Spring.NET 内置了对 asp.net mvc 2.0 和 3.0 的支持。Spring.net 2.0(NuGet 上提供的预发布版本(也内置了对版本 4.0 的支持。请考虑改用这些库。

您可能有兴趣将您的SpringDependencyResolver与 Spring.net 团队提供的进行比较。

最新更新