我在使用Unity作为IOC容器时遇到了一个奇怪的问题,已经想不出是什么原因导致的。我的WebAPI控制器中有一个服务依赖项,但它随机无法解析该依赖项。有时我需要启动应用程序3或4次,然后它突然又可以工作了。
我收到的错误消息如下:
"解析依赖关系失败,类型="Base.WebApi.Controllers.ApiUsersController",名称="(none)"。异常发生时:正在解析。异常为:InvalidOperationException - 类型IApiUserService没有可访问的构造函数。----------------------------------------------- 在抛出异常时,容器为:正在解析Base.WebApi.Controllers.ApiUsersController,(none) 正在解析构造函数Base.WebApi.Controllers.ApiUsersController(Base.BLL.Services.User.IApiUserService apiUserService)的参数"apiUserService" 正在解析Base.BLL.Services.User.IApiUserService,(none)"
我使用以下内容初始化和注册我的类型:
然而,有时它工作正常,有时却不行,我无法弄清楚为什么或者在哪里查找问题。
我收到的错误消息如下:
"解析依赖关系失败,类型="Base.WebApi.Controllers.ApiUsersController",名称="(none)"。异常发生时:正在解析。异常为:InvalidOperationException - 类型IApiUserService没有可访问的构造函数。----------------------------------------------- 在抛出异常时,容器为:正在解析Base.WebApi.Controllers.ApiUsersController,(none) 正在解析构造函数Base.WebApi.Controllers.ApiUsersController(Base.BLL.Services.User.IApiUserService apiUserService)的参数"apiUserService" 正在解析Base.BLL.Services.User.IApiUserService,(none)"
我使用以下内容初始化和注册我的类型:
public static void RegisterTypes(IUnityContainer container)
{
var myAssemblies = AppDomain.CurrentDomain.GetAssemblies().Where(a => a.FullName.StartsWith("Base") && !a.FullName.StartsWith("Base.WebApi")).ToArray();
container.RegisterType(typeof(Startup));
container.RegisterTypes(
UnityHelpers.GetTypesWithCustomAttribute<UnityIoCSingletonLifetimedAttribute>(myAssemblies),
WithMappings.FromMatchingInterface,
WithName.Default,
WithLifetime.ContainerControlled,
null
).RegisterTypes(
UnityHelpers.GetTypesWithCustomAttribute<UnityIoCTransientLifetimedAttribute>(myAssemblies),
WithMappings.FromMatchingInterface,
WithName.Default,
WithLifetime.Transient);
}
正如您所见,我正在使用单例和瞬态命名属性来定义解析我的依赖项的方式。
我的控制器如下所示:
public class ApiUsersController : ODataController
{
private readonly IApiUserService _apiUserService;
public ApiUsersController(IApiUserService apiUserService)
{
_apiUserService = apiUserService;
}
public IQueryable<ApiUserEntity> Get()
{
return this._apiUserService.GetUsers();
}
}
正如您所看到的,它依赖于用户服务,其代码如下:
[UnityIoCTransientLifetimed]
public class ApiUserService : BaseService, IApiUserService
{
private readonly IUserRepository _userRepository;
public ApiUserService(IUserRepository userRepository, IUnitOfWork uow) : base(uow)
{
_userRepository = userRepository;
}
}
API用户仓库看起来像这样:
[UnityIoCTransientLifetimed]
public class UserRepository : GenericRepository<ApiUserEntity>, IUserRepository
{
public UserRepository(IUnitOfWork unitOfWork, IDomainContext context) : base(unitOfWork, context)
{
}
扩展以下GenericRepository:
public class GenericRepository<T> : IGenericRepository<T> where T : class
{
protected readonly BaseContext Context;
public GenericRepository(IUnitOfWork unitOfWork, IBaseContext context)
{
// register this repository with the unit of work.
unitOfWork.Register(this);
Context = (BaseContext)context;
}
使用以下这个工作单元:
[UnityIoCSingletonLifetimed]
public class UnitOfWork : IUnitOfWork
{
private readonly Dictionary<string, IRepository> _repositories;
// unit of work class is responsible for creating the repository and then dispossing it when no longer needed.
public UnitOfWork()
{
_repositories = new Dictionary<string, IRepository>();
}
}
然而,有时它工作正常,有时却不行,我无法弄清楚为什么或者在哪里查找问题。
IApiUserService
在ApiUsersController
之前没有注册,这意味着它没有类型可以注入到该构造函数中。 - Ron BeyerAppDomain.CurrentDomain.GetAssemblies()
返回了什么吗?我怀疑问题的解释可能是包含ApiUserService
的程序集还没有被加载。 - Thomas Levesque