Unity IOC有时无法解决依赖性

本文关键字:解决 依赖性 IOC Unity | 更新日期: 2023-09-27 18:08:59

我在使用Unity作为IOC容器时遇到了一个奇怪的问题,我不知道是什么导致了这个问题。我在我的webapi控制器中有一个服务依赖,但它随机地无法解决这个依赖。有时我不得不启动我的应用程序3或4次,然后它突然又工作了。

我得到的错误是:

解析依赖项失败,type = "Base.WebApi.Controllers. "ApiUsersController", name = "(none)"。在解析时发生异常。异常是:InvalidOperationException—IApiUserService类型没有可访问的构造函数。-----------------------------------------------异常发生时,容器是:resoltionbase . webapi . controllers . apiuserscontroller,(none) resoltion参数"apiUserService"的构造函数Base.WebApi.Controllers.ApiUsersController(Base.BLL.Services.User. userscontroller)。IApiUserService解决Base.BLL.Services.User.IApiUserService,(none)

对于在unity中初始化和注册我的类型,我使用以下命令:

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

正如你所看到的,我正在使用singletone和transient命名属性来定义我的依赖项应该被解析的方式。

我的控制器是这样的:

public class ApiUsersController : ODataController
{
    private readonly IApiUserService _apiUserService;
    public ApiUsersController(IApiUserService apiUserService)
    {
        _apiUserService = apiUserService;
    }
    public IQueryable<ApiUserEntity> Get()
    {
        return this._apiUserService.GetUsers();
    }
}
如你所见,

依赖于user service,如下所示:

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

然而,它有时工作,有时不,我不知道为什么或在哪里看。

Unity IOC有时无法解决依赖性

多亏了一些建议,最终解决了。查看

的文档
AppDomain.CurrentDomain.GetAssemblies()

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

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

我解决这个问题的方法是使用更可靠的GetReferencedAssemblies,它加载所有的程序集,即使它们没有被使用。

var allAssemblies = new ReadOnlyCollection<Assembly>(
BuildManager.GetReferencedAssemblies().Cast<Assembly>().ToList());

重新启动了很多次,没有一个解决崩溃:)谢谢大家!对于每个想要了解更多信息的人,请查看以下答案:AppDomain的区别。GetAssemblies和BuildManager。GetReferencedAssemblies