C# 使用WebAPI的Microsoft Unity依赖项注入
我有以下体系结构:C# 使用WebAPI的Microsoft Unity依赖项注入,c#,asp.net-web-api,dependency-injection,unity-container,C#,Asp.net Web Api,Dependency Injection,Unity Container,我有以下体系结构: 数据 数据库层 WebAPI 表示层 分解器 IoC寄存器层 服务 业务层 在WebApiConfig.cs(App_Start)中,我以以下方式注册unity容器: // Unity Container Resolver var container = new UnityContainer(); //Registers the repository interface in Resolver(IoC Register Layer) var UResolver = ne
- 数据
数据库层 - WebAPI
表示层 - 分解器
IoC寄存器层 - 服务
业务层
// Unity Container Resolver
var container = new UnityContainer();
//Registers the repository interface in Resolver(IoC Register Layer)
var UResolver = new UnityRegisterContainer();
UResolver.RegisterContainer(ref container);
//Configures WebAPI DependecyResolver to use UnityResolver
config.DependencyResolver = new UnityResolver(container);
我的解析器(IoC寄存器层):
工夫
public interface IUnitOfWork : IDisposable
{
IKeyRepository Keys { get; }
int Complete();
}
如何使用unity注入类库和存储库?您可以使用构造函数注入,让
DependencyResolver
完成它的工作,并将必要的依赖项传递给类
public class KeyController : ApiController {
IKeyService keyService;
public KeyController(IKeyService keyService) {
this.keyService = keyService
}
// GET api/values
[Route("Keys")]
public IEnumerable<KeyDTO> Get() {
var Keys = keyService.GetAllKeys();
return Keys;
}
}
public interface IKeyService : IService {
IEnumerable<KeyDTO> GetAllKeys();
}
public class KeyService: IKeyService {
IUnitOfWork UOW;
public KeyService(IUnitOfWork uow) {
this.UOW = uow
}
/// <summary>
/// Get all Keys
/// </summary>
/// <returns></returns>
public IEnumerable<KeyDTO> GetAllKeys() {
return Mapper.Map<IEnumerable<Key>, IEnumerable<KeyDTO>>(UOW.Keys.GetAllKeys());
}
}
public class UnitOfWork: IUnitOfWork {
public UnitOfWork(IKeyRepository repository) {
Keys = repository;
}
IKeyRepository Keys { get;private set }
public int Complete(){...}
}
公共类KeyController:ApiController{
IKeyService-keyService;
公钥控制器(IKeyService-keyService){
this.keyService=keyService
}
//获取api/值
[路线(“钥匙”)]
公共IEnumerable Get(){
var Keys=keyService.GetAllKeys();
返回键;
}
}
公共接口IKeyService:IService{
IEnumerable GetAllKeys();
}
公共类密钥服务:IKeyService{
i工作单元UOW;
公钥服务(IUnitOfWork uow){
this.UOW=UOW
}
///
///拿到所有钥匙
///
///
公共IEnumerable GetAllKeys(){
返回Mapper.Map(UOW.Keys.GetAllKeys());
}
}
公共类UnitOfWork:IUnitOfWork{
公共工作单元(IKeyRepository存储库){
密钥=存储库;
}
IKeyRepository密钥{get;private set}
公共int Complete(){…}
}
您可以使用构造函数注入,让DependencyResolver
完成它的工作,并将必要的依赖项传递给类
public class KeyController : ApiController {
IKeyService keyService;
public KeyController(IKeyService keyService) {
this.keyService = keyService
}
// GET api/values
[Route("Keys")]
public IEnumerable<KeyDTO> Get() {
var Keys = keyService.GetAllKeys();
return Keys;
}
}
public interface IKeyService : IService {
IEnumerable<KeyDTO> GetAllKeys();
}
public class KeyService: IKeyService {
IUnitOfWork UOW;
public KeyService(IUnitOfWork uow) {
this.UOW = uow
}
/// <summary>
/// Get all Keys
/// </summary>
/// <returns></returns>
public IEnumerable<KeyDTO> GetAllKeys() {
return Mapper.Map<IEnumerable<Key>, IEnumerable<KeyDTO>>(UOW.Keys.GetAllKeys());
}
}
public class UnitOfWork: IUnitOfWork {
public UnitOfWork(IKeyRepository repository) {
Keys = repository;
}
IKeyRepository Keys { get;private set }
public int Complete(){...}
}
公共类KeyController:ApiController{
IKeyService-keyService;
公钥控制器(IKeyService-keyService){
this.keyService=keyService
}
//获取api/值
[路线(“钥匙”)]
公共IEnumerable Get(){
var Keys=keyService.GetAllKeys();
返回键;
}
}
公共接口IKeyService:IService{
IEnumerable GetAllKeys();
}
公共类密钥服务:IKeyService{
i工作单元UOW;
公钥服务(IUnitOfWork uow){
this.UOW=UOW
}
///
///拿到所有钥匙
///
///
公共IEnumerable GetAllKeys(){
返回Mapper.Map(UOW.Keys.GetAllKeys());
}
}
公共类UnitOfWork:IUnitOfWork{
公共工作单元(IKeyRepository存储库){
密钥=存储库;
}
IKeyRepository密钥{get;private set}
公共int Complete(){…}
}
尽管首选构造函数注入(有时不建议使用属性注入),但也可以在具有依赖项的实现类中使用[Dependency]
属性,如下所示:
public class KeyService: IService
{
// Public setter, private getter, so you can mock and manually assing in Unit Tests
[Dependency]
public IUnitOfWork UOW { private get; set; }
public IEnumerable<KeyDTO> GetAllKeys()
{
return Mapper.Map<IEnumerable<Key>, IEnumerable<KeyDTO>>(UOW.Keys.GetAllKeys());
}
}
公共类密钥服务:iSeries设备
{
//公共setter、私有getter,因此您可以在单元测试中模拟和手动分配
[依赖性]
公共IUnitOfWork{private get;set;}
公共IEnumerable GetAllKeys()
{
返回Mapper.Map(UOW.Keys.GetAllKeys());
}
}
请参见尽管首选构造函数注入(有时不建议使用属性注入),但也可以在具有依赖关系的实现类中使用
[Dependency]
属性,如下所示:
public class KeyService: IService
{
// Public setter, private getter, so you can mock and manually assing in Unit Tests
[Dependency]
public IUnitOfWork UOW { private get; set; }
public IEnumerable<KeyDTO> GetAllKeys()
{
return Mapper.Map<IEnumerable<Key>, IEnumerable<KeyDTO>>(UOW.Keys.GetAllKeys());
}
}
公共类密钥服务:iSeries设备
{
//公共setter、私有getter,因此您可以在单元测试中模拟和手动分配
[依赖性]
公共IUnitOfWork{private get;set;}
公共IEnumerable GetAllKeys()
{
返回Mapper.Map(UOW.Keys.GetAllKeys());
}
}
请参见您可以使用构造函数注入查看RegisterContainer,我认为您需要的重载是。所以您可以这样调用它:
container.RegisterType(新的层次结构CallifetimeManager())代码>。也就是说,您将需要一个IKeyService
接口,并且您必须将它指向具体的实现(如果您想让您的模拟/测试生活更容易的话)。为什么您的UnityContainer
作为ref
传入参数?我对单元库不太熟悉。容器是一个struct
?您可以使用构造函数注入查看RegisterContainer
,我认为您所追求的重载是。所以您可以这样调用它:container.RegisterType(新的层次结构CallifetimeManager())代码>。也就是说,您将需要一个IKeyService
接口,并且您必须将它指向具体的实现(如果您想让您的模拟/测试生活更容易的话)。为什么您的UnityContainer
作为ref
传入参数?我对单元库不太熟悉。容器是一个结构吗?
?正如您所说的,由于许多原因,不建议使用属性注入。您不确切地知道何时注入属性,您将无法在构造函数中访问它们(如果您需要它们),并且它会使用属性污染您的代码,这意味着您的代码现在绑定到此库。对于一些东西来说这可能很酷(比如一个记录器),但正如@robinet所说,你应该更喜欢构造函数注入。除非你有一个依赖于10+ITaxCalculationStrategy
的TaxStrategyFactory
,并且你进入任何ITaxCalculationStrategy
的唯一入口点都是一些不需要构造函数初始化的方法(可能除了依赖项解析)。我宁愿在工厂中有10多个注入属性(最终只会是一个分派器),而不是在构造函数中有10多个参数。税务计算可能不是最好的例子,但我遇到过这样的问题。在本例中,我可能会给TaxStrategyFactory
一个解析器实例。通过这种方式,您可以在一个明确的级别上处理依赖项解析,而不是在任何地方。老实说,我主要关心的是属性级别的属性注入。这是可能的
public class KeyController : ApiController {
IKeyService keyService;
public KeyController(IKeyService keyService) {
this.keyService = keyService
}
// GET api/values
[Route("Keys")]
public IEnumerable<KeyDTO> Get() {
var Keys = keyService.GetAllKeys();
return Keys;
}
}
public interface IKeyService : IService {
IEnumerable<KeyDTO> GetAllKeys();
}
public class KeyService: IKeyService {
IUnitOfWork UOW;
public KeyService(IUnitOfWork uow) {
this.UOW = uow
}
/// <summary>
/// Get all Keys
/// </summary>
/// <returns></returns>
public IEnumerable<KeyDTO> GetAllKeys() {
return Mapper.Map<IEnumerable<Key>, IEnumerable<KeyDTO>>(UOW.Keys.GetAllKeys());
}
}
public class UnitOfWork: IUnitOfWork {
public UnitOfWork(IKeyRepository repository) {
Keys = repository;
}
IKeyRepository Keys { get;private set }
public int Complete(){...}
}
public class KeyService: IService
{
// Public setter, private getter, so you can mock and manually assing in Unit Tests
[Dependency]
public IUnitOfWork UOW { private get; set; }
public IEnumerable<KeyDTO> GetAllKeys()
{
return Mapper.Map<IEnumerable<Key>, IEnumerable<KeyDTO>>(UOW.Keys.GetAllKeys());
}
}