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寄存器层
  • 服务
    业务层
在WebApiConfig.cs(App_Start)中,我以以下方式注册unity容器:

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