Asp.net web api ASP.NET Web API控制器:通过IOC容器与重载构造函数的依赖项注入

Asp.net web api ASP.NET Web API控制器:通过IOC容器与重载构造函数的依赖项注入,asp.net-web-api,constructor,dependency-injection,inversion-of-control,ioc-container,Asp.net Web Api,Constructor,Dependency Injection,Inversion Of Control,Ioc Container,我有一个依赖于服务的控制器。出于单元测试的目的,我需要能够传入该服务,因此我将该服务传入构造函数 我的问题是,像这样重载构造函数的缺点是什么: public class MyController : ApiController { protected IStorageService StorageService; protected MyController() { StorageService = StorageServiceFactory.Creat

我有一个依赖于服务的控制器。出于单元测试的目的,我需要能够传入该服务,因此我将该服务传入构造函数

我的问题是,像这样重载构造函数的缺点是什么:

public class MyController : ApiController
{
    protected IStorageService StorageService;

    protected MyController()
    {
        StorageService = StorageServiceFactory.CreateStorageService(User.Identity as ClaimsIdentity);
    }

    protected MyController(IStorageService storageService)
    {
        StorageService = storageService;
    }
}
public class MyController : ApiController
{
    protected IStorageService StorageService;

    protected MyController()
    {
        StorageService = StorageServiceFactory.CreateStorageService(User.Identity as ClaimsIdentity);
    }

    protected MyController(IStorageService storageService)
    {
        StorageService = storageService;
    }
}
IocContainer.ResolveInstance<IStorageService>(User.Identity);
。。。单元测试将调用第二个构造函数,而正常用例将使用第一个构造函数。。。与放弃第一个构造函数并使用IOC容器注入依赖项相比


在这种特殊情况下,因为我的具体服务需要User.Identity(这是特定于请求的),所以从IOC容器中执行此操作似乎很有挑战性。但是人们这样做肯定有其原因,所以我想得到一些澄清。

我会选择IocContainer,因为它更易于使用,而且您不必为单元测试做任何不同的事情。它将是一种更易于配置的方法,使实现依赖于抽象。工厂模式也很有用(与StorageServiceFactory一样),但IocContainer也允许您轻松使用最新的模拟框架

代码如下所示:

public class MyController : ApiController
{
    protected IStorageService StorageService;

    protected MyController()
    {
        StorageService = StorageServiceFactory.CreateStorageService(User.Identity as ClaimsIdentity);
    }

    protected MyController(IStorageService storageService)
    {
        StorageService = storageService;
    }
}
public class MyController : ApiController
{
    protected IStorageService StorageService;

    protected MyController()
    {
        StorageService = StorageServiceFactory.CreateStorageService(User.Identity as ClaimsIdentity);
    }

    protected MyController(IStorageService storageService)
    {
        StorageService = storageService;
    }
}
IocContainer.ResolveInstance<IStorageService>(User.Identity);
IStorageService的实现如下所示

public class StorageServiceImplementation : IStorageService
{
    public StorageServiceImplementation(ClaimsIdentity identity)
    {
    }
//IStorageService.Methods
}
这就是如何使用结构映射创建IStorageService实例并将ClaimsIdentity作为参数传递的方法

public static T ResolveInstanceWithCtorValue<T, I>(I ctorValue)
        {
            return ObjectFactory.Container.With(ctorValue).GetInstance<T>();
        }
public static T ResolveInstanceWithCtorValue(I ctorValue)
{
返回ObjectFactory.Container.With(ctorValue.GetInstance();
}
然后像这样解决它:

public class MyController : ApiController
{
    protected IStorageService StorageService;

    protected MyController()
    {
        StorageService = StorageServiceFactory.CreateStorageService(User.Identity as ClaimsIdentity);
    }

    protected MyController(IStorageService storageService)
    {
        StorageService = storageService;
    }
}
public class MyController : ApiController
{
    protected IStorageService StorageService;

    protected MyController()
    {
        StorageService = StorageServiceFactory.CreateStorageService(User.Identity as ClaimsIdentity);
    }

    protected MyController(IStorageService storageService)
    {
        StorageService = storageService;
    }
}
IocContainer.ResolveInstance<IStorageService>(User.Identity);
IocContainer.ResolveInstance(User.Identity);

如果还有更多问题,请告诉我。

有多个构造函数是一种反模式。看一看,了解原因。@Steven谢谢!这就是我想要的解释。谢谢!但是,无法从解析IStorageService的位置访问User.Identity。请看我的相关问题: