【ASP.Net】 DependencyResolver

MSDN:

这个属性是在配置web api的httpconfiguration的时候配置的。 那么他到底有什么作用呢?

 

根据 流程图 中所示, server 中的controller会使用相应的orm进行资源访问, 所以orm的实例如果在controll类中实例化, 则会导致代码多种不优雅:

  • 导致Controller与orm存在依赖关系,orm的改动必然会影响到Controller。
  • 如果orm存在其他的依赖关系, Controller同样需要配置。
  • 会导致单元测试很难进行。

所以我们需要将orm的实例注入到Controller中, 这就是DependencyResolver为何而出现了。

当web api根据route找到对应Controller时候, 会首先通过DependencyResolver的getservice方法去创建orm实例。但是一般情况下, DependencyResolver都是使用在web api与已存在的IOC容器之间, 作为他们之间的一个桥梁。因为需要DependencyResolver控制你的注入的对象的生命周期

目前有很多很好用的IOC容易例如: UnityCastle Windsor, Spring.Net, Autofac, Ninject, StructureMap.

来自MSDN的一段代码说明了如何使用IOC容器去做到在Controller中注入orm的实例:

using Microsoft.Practices.Unity;
using System;
using System.Collections.Generic;
using System.Web.Http.Dependencies;

public class UnityResolver : IDependencyResolver
{
    protected IUnityContainer container;

    public UnityResolver(IUnityContainer container)
    {
        if (container == null)
        {
            throw new ArgumentNullException("container");
        }
        this.container = container;
    }

    public object GetService(Type serviceType)
    {
        try
        {
            return container.Resolve(serviceType);
        }
        catch (ResolutionFailedException)
        {
            return null;
        }
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
        try
        {
            return container.ResolveAll(serviceType);
        }
        catch (ResolutionFailedException)
        {
            return new List<object>();
        }
    }

    public IDependencyScope BeginScope()
    {
        var child = container.CreateChildContainer();
        return new UnityResolver(child);
    }

    public void Dispose()
    {
        Dispose(true);
    }

    protected virtual void Dispose(bool disposing)
    {
        container.Dispose();
    }
}

 我下面这段可能会很重要。也就是DR是如何在web api与ioc容器之间起到一个桥梁的作用的。

Web API会根据Request创建Controller, 然而绑定到httpconfiguration的DR会首先执行BeginScope方法。 这个方法会返回一个子scope。

然后web api根据返回的scope去创建相应的Controller,当Request执行完毕, web api再根据scope去调用dispose释放这些Controller的依赖关系。

然而实现beginscope这个方法取决于你采用的ioc容器

类似如下:

 

public IDependencyScope BeginScope()
{
    var child = container.CreateChildContainer();
    return new UnityResolver(child);
}

 

posted @ 2018-09-10 18:14  YanyuWu  阅读(161)  评论(0)    收藏  举报