Unity IOC有时无法解决依赖问题

时间:2015-08-19 18:29:44

标签: c# asp.net-web-api unity-container

我使用Unity作为IOC容器时遇到了一个奇怪的问题,并且我想出了什么可能导致它。我的webapi控制器中有一个服务依赖项,但随机无法解决此依赖项。有时我必须开始我的应用程序3到4次,然后它突然再次起作用。

我得到的错误是:

  

依赖关系的解析失败,输入=" Base.WebApi.Controllers.ApiUsersController",name ="(none)"。在解决时发生异常:异常是:InvalidOperationException - 类型IApiUserService没有可访问的构造函数。 - - - - - - - - - - - - - - - - - - - - - - - - 当时例外,容器是:解析Base.WebApi.Controllers.ApiUsersController,(无)解析参数" apiUserService"构造函数Base.WebApi.Controllers.ApiUsersController(Base.BLL.Services.User.IApiUserService apiUserService)解析Base.BLL.Services.User.IApiUserService,(无)

为了统一初始化和注册我的类型,请使用以下内容:

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

然而,它有时会起作用,有时它不会,我无法弄清楚为什么或在哪里看。

1 个答案:

答案 0 :(得分:1)

最后通过一些建议解决了这个问题。查看

的文档
updated

它说: 获取已加载到此应用程序域的执行上下文中的程序集。

这基本上意味着它只在实际需要时加载程序集。

我解决它的方法是使用更可靠的GetReferencedAssemblies加载所有组件,即使它们没有被使用。

AppDomain.CurrentDomain.GetAssemblies()

重启很多次而不是一次解决崩溃:)谢谢大家!对于寻找更多信息的每个人,请查看此SO答案:Difference between AppDomain.GetAssemblies and BuildManager.GetReferencedAssemblies