公寓管理费系统注入IUnitOfWork到ApartmentManager遇Autofac依赖错误
错误信息
Autofac.Core.DependencyResolutionException: An exception was thrown while activating Business.Concrete.ApartmentManager -> DataAccess.Concrete.UnitOfWork.UnitOfWork.
---> Autofac.Core.DependencyResolutionException: None of the constructors found on type 'DataAccess.Concrete.UnitOfWork.UnitOfWork' can be invoked with the available services and parameters:
Cannot resolve parameter 'DataAccess.Concrete.EntityFramework.Context.ApartmentDuesManagementContext context' of constructor 'Void .ctor(DataAccess.Concrete.EntityFramework.Context.ApartmentDuesManagementContext)'.
问题背景
开发公寓管理费管理系统时,尝试将IUnitOfWork注入到ApartmentManager的构造函数中时触发上述错误。移除IUnitOfWork参数后错误消失,但无法使用工作单元模式实现批量提交(比如一次性插入100条记录),需要解决依赖注入问题。
相关代码
Autofac注册模块
public class AutofacBusinessModule : Module { protected override void Load(ContainerBuilder builder) { builder.RegisterType<UnitOfWork>().As<IUnitOfWork>() .InstancePerLifetimeScope(); builder.RegisterType<EfApartmentDal>().As<IApartmentDal>() .InstancePerLifetimeScope(); builder.RegisterType<ApartmentManager>() .As<IApartmentService>() .InstancePerLifetimeScope(); } }
IUnitOfWork接口
public interface IUnitOfWork { Task CommitAsync(); void Commit(); //Task<int> SaveChangesAsync(); //Task BeginTransactionAsync(); //Task CommitTransactionAsync(); //Task RollbackTransactionAsync(); //public interface IEntityRepository<T> where T : class, IEntity, new() //{ // Task AddRangeAsync(IEnumerable<T> entities); //} //public interface IApartmentRepository : IEntityRepository<Apartment> { } }
UnitOfWork实现类
public class UnitOfWork : IUnitOfWork { private readonly ApartmentDuesManagementContext _context; //private IDbContextTransaction _transaction; public UnitOfWork(ApartmentDuesManagementContext context) { _context = context; } public void Commit() { _context.SaveChanges(); } public async Task CommitAsync() { await _context.SaveChangesAsync(); } }
EfApartmentDal实现类
public class EfApartmentDal : EfEntityRepositoryBase<Apartment, ApartmentDuesManagementContext>, IApartmentDal { }
IApartmentDal接口
public interface IApartmentDal : IEntityRepository<Apartment> { }
IApartmentService接口
public interface IApartmentService { IDataResult<List<Apartment>> GetList(); Task<IDataResult<Task<IEnumerable<Apartment>>>> AddRangeAsync<TEntity>(IEnumerable<Apartment> apartments); }
ApartmentManager实现类
public class ApartmentManager : IApartmentService { private readonly IApartmentDal _apartmentDal; private readonly IUnitOfWork _unitOfWork; public ApartmentManager(IApartmentDal apartmentDal, IUnitOfWork unitOfWork) { _apartmentDal = apartmentDal; _unitOfWork = unitOfWork; } public IDataResult<List<Apartment>> GetList() { return new SuccessDataResult<List<Apartment>>(_apartmentDal.GetList(), "Apartmanlar basarili bir sekilde listelendi."); } public async Task<IDataResult<Task<IEnumerable<Apartment>>>> AddRangeAsync<TEntity>(IEnumerable<Apartment> apartments) { await _apartmentDal.AddRangeAsync(apartments); await _unitOfWork.CommitAsync(); return new SuccessDataResult<Task<IEnumerable<Apartment>>>(Task.FromResult(apartments), "Kayıt ekleme başarılı"); } }
解决方案
1. 注册DbContext到Autofac容器
错误的核心原因是Autofac容器中没有注册ApartmentDuesManagementContext,导致无法解析UnitOfWork构造函数中的上下文参数。需要在AutofacBusinessModule的Load方法中添加DbContext的注册:
public class AutofacBusinessModule : Module { protected override void Load(ContainerBuilder builder) { // 注册DbContext,生命周期和其他服务保持一致 builder.RegisterType<ApartmentDuesManagementContext>() .InstancePerLifetimeScope(); builder.RegisterType<UnitOfWork>().As<IUnitOfWork>() .InstancePerLifetimeScope(); builder.RegisterType<EfApartmentDal>().As<IApartmentDal>() .InstancePerLifetimeScope(); builder.RegisterType<ApartmentManager>() .As<IApartmentService>() .InstancePerLifetimeScope(); } }
2. 确保上下文实例共享
使用InstancePerLifetimeScope可以保证在同一个请求/生命周期范围内,EfApartmentDal和UnitOfWork拿到的是同一个ApartmentDuesManagementContext实例,这样调用AddRangeAsync添加多条记录后,通过UnitOfWork.CommitAsync()就能一次性提交所有变更,符合工作单元的设计意图。
3. 优化冗余泛型(可选)
你的AddRangeAsync<TEntity>方法中的泛型参数TEntity没有实际使用,可以移除它简化代码:
public async Task<IDataResult<IEnumerable<Apartment>>> AddRangeAsync(IEnumerable<Apartment> apartments) { await _apartmentDal.AddRangeAsync(apartments); await _unitOfWork.CommitAsync(); return new SuccessDataResult<IEnumerable<Apartment>>(apartments, "Kayıt ekleme başarılı"); }
对应的接口也需要修改:
public interface IApartmentService { IDataResult<List<Apartment>> GetList(); Task<IDataResult<IEnumerable<Apartment>>> AddRangeAsync(IEnumerable<Apartment> apartments); }
内容的提问来源于stack exchange,提问作者nikki

