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>();
}
}
然而,它有时工作,有时不,我不知道为什么或在哪里看。
多亏了一些建议,最终解决了。查看
的文档AppDomain.CurrentDomain.GetAssemblies()
的内容如下:获取已加载到此应用程序域的执行上下文中的程序集。
这基本上意味着它只在实际需要时加载程序集。
我解决这个问题的方法是使用更可靠的GetReferencedAssemblies,它加载所有的程序集,即使它们没有被使用。
var allAssemblies = new ReadOnlyCollection<Assembly>(
BuildManager.GetReferencedAssemblies().Cast<Assembly>().ToList());
重新启动了很多次,没有一个解决崩溃:)谢谢大家!对于每个想要了解更多信息的人,请查看以下答案:AppDomain的区别。GetAssemblies和BuildManager。GetReferencedAssemblies