如何在外部库的ASP.NET WebAPI中访问依赖关系解析器

时间:2019-01-28 23:55:30

标签: c# asp.net-web-api dependency-injection

我正在设计一个NuGet程序包,该程序包将由我的应用程序使用。由于该项目已经实现了架构,因此我需要提供一种方法,可以在控制器范围之外使用MVC和Web API的依赖注入实例化对象。 目前,我有一个可在MVC项目中工作的类,通过使用DependencyResolver实例化对象

public abstract class MyBaseClass<T> where T : class
  {
    public static T Instance
    {
      get
      {
          return DependencyResolver.Current.GetService<T>();
      }
    }
  }

但是,当从WebAPI项目中使用同一类时,不存在DependencyResolver,因此Im无法检索任何对象。

我尝试通过HttpContext访问依赖项解析器,但操作不成功。您有什么办法可以通过NuGet软件包访问它?

谢谢!

1 个答案:

答案 0 :(得分:0)

如果可能,我建议避免使用服务定位器模式,而是通过构造函数注入依赖项:

public abstract class MyBaseClass<T> where T : class
{
    public MyBaseClass(T instance)
    {
        Instance = instance;
    }

    public T Instance { get; }
}

这将允许您通过选择的任何“主”入口点(例如MVC或WebAPI)使用软件包。届时,消费者有责任提供必要的依赖关系解决策略。


以下是该包的使用者(在本例中为WebAPI服务)如何实现上述代码的示例:

public class MyWebApiClass : MyBaseClass<MyDependency>
{
    public MyWebApiClass(MyDependency resolvedDependency) : base(resolvedDependency) { }
}

public class MyDependency
{
    public string Foo { get; set; }

    public MyDependency()
    {
        Foo = "Bar";
    }
}

然后,消费服务还将注册那些依赖项:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
    services.AddTransient<MyDependency>();
    services.AddTransient<MyWebApiClass>();
}

...并根据需要注入,从而允许框架解决依赖关系(工作中的IoC):

[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
    private readonly MyWebApiClass _myWebApiClass;

    public ValuesController(MyWebApiClass myWebApiClass)
    {
        _myWebApiClass = myWebApiClass;
    }

    // GET api/values
    [HttpGet]
    public ActionResult<IEnumerable<string>> Get()
    {
        return new string[] { _myWebApiClass.Instance.Foo };
    }
}

调用上面的GET端点,我们可以看到实例在MyBaseClass中得到解析:

enter image description here