如何对继承class使用依赖注入?
How to use dependency injection for inherited class?
这里我用的是依赖注入框架(Ninject),效果很好。但是面临的问题之一是,我有一个基础 class,它带有一个实现接口的构造函数。
public class BaseApiController : ApiController
{
readonly IAccessService _accessService;
public BaseApiController(IAccessService accessService)
{
this._accessService = accessService;
}
}
当我从这个基础 class 继承到所有其他控制器时,这些控制器具有实现自己接口的构造函数。我收到错误 'BaseApiController' does not contain a constructor that takes 0 arguments,好的,我明白了。导出的 class 是
public class DiscoverController : BaseApiController
{
readonly IDiscoverService _discoverService;
readonly IAccessService _accessService;
public DiscoverController(IDiscoverService discoverService,IAccessService accessService)
{
_accessService = accessService;
_discoverService = discoverService;
}
}
如果不修改派生的 class ctor 以采用类似的参数并将该值传递给基本 ctor,我怎么能做到这一点,如果您建议更好的方法来处理这个问题,我将不胜感激?
尝试修改派生构造函数以将参数传递给基础 class:
public class DiscoverController : BaseApiController
{
readonly IDiscoverService _discoverService;
readonly IAccessService _accessService;
public DiscoverController(IDiscoverService discoverService,IAccessService accessService) : base(accessService)
{
_discoverService = discoverService;
}
}
正如@Christian 所说,错误是 C# 编译器错误,因为您必须传递依赖项。
您可能已经注意到,拥有这样的基础 class 并不是一种真正令人愉快的工作方式。您必须将此依赖项注入每个控制器并将其传递给基本控制器。更糟糕的是,当基础控制器需要第二个依赖项时,您将不得不更新控制器的所有构造函数。
你做错的是你:
- 使用继承而不是组合
- 使用基础 class 来应用横切关注点(当您向该基础添加第二个横切关注点时,这将违反 Single Responsibility Principle and Open/Closed Principle class).
您在基地 class 中使用这个 IAccessService
可能是为了进行某些安全检查。除了使用 base classes,还有更好的方法。一个通用的解决方案是使用装饰器,但这不适用于 Web API。相反,对于 Web API,您可以使用 DelegateHandlers 并将它们添加到管道中。这样的处理程序就像装饰器一样,允许您透明地应用横切关注点,例如安全性。
使用 :base 关键字修改 DiscoverController(您将使用父构造函数):
https://msdn.microsoft.com/en-us/library/hfw7t1ce.aspx
这里我用的是依赖注入框架(Ninject),效果很好。但是面临的问题之一是,我有一个基础 class,它带有一个实现接口的构造函数。
public class BaseApiController : ApiController
{
readonly IAccessService _accessService;
public BaseApiController(IAccessService accessService)
{
this._accessService = accessService;
}
}
当我从这个基础 class 继承到所有其他控制器时,这些控制器具有实现自己接口的构造函数。我收到错误 'BaseApiController' does not contain a constructor that takes 0 arguments,好的,我明白了。导出的 class 是
public class DiscoverController : BaseApiController
{
readonly IDiscoverService _discoverService;
readonly IAccessService _accessService;
public DiscoverController(IDiscoverService discoverService,IAccessService accessService)
{
_accessService = accessService;
_discoverService = discoverService;
}
}
如果不修改派生的 class ctor 以采用类似的参数并将该值传递给基本 ctor,我怎么能做到这一点,如果您建议更好的方法来处理这个问题,我将不胜感激?
尝试修改派生构造函数以将参数传递给基础 class:
public class DiscoverController : BaseApiController
{
readonly IDiscoverService _discoverService;
readonly IAccessService _accessService;
public DiscoverController(IDiscoverService discoverService,IAccessService accessService) : base(accessService)
{
_discoverService = discoverService;
}
}
正如@Christian 所说,错误是 C# 编译器错误,因为您必须传递依赖项。
您可能已经注意到,拥有这样的基础 class 并不是一种真正令人愉快的工作方式。您必须将此依赖项注入每个控制器并将其传递给基本控制器。更糟糕的是,当基础控制器需要第二个依赖项时,您将不得不更新控制器的所有构造函数。
你做错的是你:
- 使用继承而不是组合
- 使用基础 class 来应用横切关注点(当您向该基础添加第二个横切关注点时,这将违反 Single Responsibility Principle and Open/Closed Principle class).
您在基地 class 中使用这个 IAccessService
可能是为了进行某些安全检查。除了使用 base classes,还有更好的方法。一个通用的解决方案是使用装饰器,但这不适用于 Web API。相反,对于 Web API,您可以使用 DelegateHandlers 并将它们添加到管道中。这样的处理程序就像装饰器一样,允许您透明地应用横切关注点,例如安全性。
使用 :base 关键字修改 DiscoverController(您将使用父构造函数): https://msdn.microsoft.com/en-us/library/hfw7t1ce.aspx