在 winform 中使用 autofac (Autofac.Core.DependencyResolutionException HResult=0x80131500) 使用 UnitOfWork 和存储库模式实现 DI
Implementing DI with UnitOfWork and repository patterns in winform use autofac (Autofac.Core.DependencyResolutionException HResult=0x80131500)
所以让我们从 DbContext 开始
public class SIMContext : DbContext
{
public SIMContext()
{
}
public SIMContext(DbContextOptions<SIMContext> options): base(options)
{
}
public virtual DbSet<Department> Departments { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(ConfigurationManager.ConnectionStrings["SIMContext"].ConnectionString);
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.ApplyConfiguration(new DepartmentConfiguration());
}
}
这是我的 IUnitOfWork:
public interface IUnitOfWork : IDisposable
{
IDepartmentRepository Departments { get; }
int Complete();
}
这是 UnitOfWork:
public class UnitOfWork : IUnitOfWork
{
private readonly SIMContext _context;
public UnitOfWork(SIMContext context)
{
_context = context;
Departments = new DepartmentRepository(_context);
}
public IDepartmentRepository Departments { get; private set; }
public int Complete()
{
return _context.SaveChanges();
}
private bool disposed = false;
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
_context.Dispose();
}
}
this.disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
这是我的 IRepository:
public interface IRepository<TEntity> where TEntity : class
{
Task<TEntity> GetByIdAsync(object id);
Task<IEnumerable<TEntity>> GetAllAsync();
Task<TEntity> FindAsync(Expression<Func<TEntity, bool>> predicate, string[] includes = null);
Task<IEnumerable<TEntity>> FindAllAsync(Expression<Func<TEntity, bool>> predicate, string[] includes = null);
Task<IEnumerable<TEntity>> FindAllAsync(Expression<Func<TEntity, bool>> predicate, int take, int skip);
Task<TEntity> SingleOrDefault(Expression<Func<TEntity, bool>> predicate);
Task<TEntity> AddAsync(TEntity entity);
Task<IEnumerable<TEntity>> AddRangeAsync(IEnumerable<TEntity> entities);
void Remove(TEntity entity);
void RemoveRange(IEnumerable<TEntity> entities);
}
这是我的存储库:
public class Repository<TEntity> : IRepository<TEntity> where TEntity : class
{
protected readonly DbContext Context;
internal DbSet<TEntity> dbSet;
public Repository(DbContext context)
{
Context = context;
dbSet = Context.Set<TEntity>();
}
public async Task<TEntity> AddAsync(TEntity entity)
{
await dbSet.AddAsync(entity);
return entity;
}
public async Task<IEnumerable<TEntity>> AddRangeAsync(IEnumerable<TEntity> entities)
{
await dbSet.AddRangeAsync(entities);
return entities;
}
public async Task<TEntity> FindAsync(Expression<Func<TEntity, bool>> predicate, string[] includes = null)
{
IQueryable<TEntity> query = dbSet;
if (includes != null)
foreach (var incluse in includes)
query = query.Include(incluse);
return await query.SingleOrDefaultAsync(predicate);
}
public async Task<IEnumerable<TEntity>> FindAllAsync(Expression<Func<TEntity, bool>> predicate, string[] includes = null)
{
IQueryable<TEntity> query = dbSet;
if (includes != null)
foreach (var include in includes)
query = query.Include(include);
return await query.Where(predicate).ToListAsync();
}
public async Task<IEnumerable<TEntity>> FindAllAsync(Expression<Func<TEntity, bool>> predicate, int take, int skip)
{
return await dbSet.Where(predicate).Skip(skip).Take(take).ToListAsync();
}
public async Task<TEntity> GetByIdAsync(object id)
{
return await dbSet.FindAsync(id);
}
public async Task<IEnumerable<TEntity>> GetAllAsync()
{
return await dbSet.ToListAsync();
}
public void Remove(TEntity entity)
{
dbSet.Remove(entity);
}
public void RemoveRange(IEnumerable<TEntity> entities)
{
dbSet.RemoveRange(entities);
}
public async Task<TEntity> SingleOrDefault(Expression<Func<TEntity, bool>> predicate)
{
return await dbSet.SingleOrDefaultAsync(predicate);
}
}
这是 IDepartmentRepository :
public interface IDepartmentRepository: IRepository<Department>
{
}
这是 DepartmentRepository :
public class DepartmentRepository : Repository<Department>, IDepartmentRepository
{
public DepartmentRepository(SIMContext context) : base(context)
{
}
public SIMContext SIMContext
{
get { return Context as SIMContext; }
}
}
这是我的程序 class :
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
public static IContainer Container;
[STAThread]
static void Main()
{
DevExpress.UserSkins.BonusSkins.Register();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Container = Configure();
Application.Run(new XtraMain(Container.Resolve<IUnitOfWork>()));
}
static IContainer Configure()
{
var builder = new ContainerBuilder();
builder.RegisterType<UnitOfWork>().As<IUnitOfWork>();
builder.RegisterType<XtraMain>();
return builder.Build();
}
}
这是我的 XtraMain 表单:
private readonly IUnitOfWork unitOfWork;
public XtraMain(IUnitOfWork unitOfWork)
{
InitializeComponent();
this.unitOfWork = unitOfWork;
}
private void bbtnDepartment_ItemClick(object sender, ItemClickEventArgs e)
{
Frm_Department frme = new(unitOfWork)
{
Name = "Frm_Department"
};
ViewChildForm(frme);
}
但是当我 运行 程序时,我在这一行出现错误:
Application.Run(new XtraMain(Container.Resolve<IUnitOfWork>()));
错误是:
Autofac.Core.DependencyResolutionException
HResult=0x80131500
Message=An exception was thrown while activating Smart_Industrial_Management.Persistence.UnitOfWork.
Source=Autofac
StackTrace:
at Autofac.Core.Resolving.Middleware.ActivatorErrorHandlingMiddleware.Execute(ResolveRequestContext context, Action1 next) at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext ctxt) at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext ctxt) at Autofac.Core.Resolving.Middleware.SharingMiddleware.Execute(ResolveRequestContext context, Action
1 next)
at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.b__1(ResolveRequestContext ctxt)
at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.b__1(ResolveRequestContext ctxt)
at Autofac.Core.Resolving.Middleware.CircularDependencyDetectorMiddleware.Execute(ResolveRequestContext context, Action1 next) at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext ctxt) at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, ResolveRequest request) at Autofac.Core.Resolving.ResolveOperation.ExecuteOperation(ResolveRequest request) at Autofac.Core.Lifetime.LifetimeScope.ResolveComponent(ResolveRequest request) at Autofac.ResolutionExtensions.TryResolveService(IComponentContext context, Service service, IEnumerable
1 parameters, Object& instance)
at Autofac.ResolutionExtensions.ResolveService(IComponentContext context, Service service, IEnumerable1 parameters) at Autofac.ResolutionExtensions.Resolve[TService](IComponentContext context, IEnumerable
1 parameters)
at Smart_Industrial_Management.Program.Main() in C:\Users\MBoua\source\repos\SIM Windows7 EF Core5\Smart Industrial Management\Program.cs:line 49
This exception was originally thrown at this call stack:
[External Code]
Inner Exception 1:
DependencyResolutionException: None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'Smart_Industrial_Management.Persistence.UnitOfWork' can be invoked with the available services and parameters:
Cannot resolve parameter 'Smart_Industrial_Management.Persistence.SIMContext context' of constructor 'Void .ctor(Smart_Industrial_Management.Persistence.SIMContext)'.
我该如何解决这个问题?
DependencyResolutionException: None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'Smart_Industrial_Management.Persistence.UnitOfWork' can be invoked with the available services and parameters: Cannot resolve parameter 'Smart_Industrial_Management.Persistence.SIMContext context' of constructor 'Void .ctor(Smart_Industrial_Management.Persistence.SIMContext)'.
您似乎在配置 Autofac 时没有注册 SIMContext
。在您的 Configure
方法中添加以下注册可能会有所帮助:
builder.RegisterType<SIMContext>().AsSelf();
所以让我们从 DbContext 开始
public class SIMContext : DbContext
{
public SIMContext()
{
}
public SIMContext(DbContextOptions<SIMContext> options): base(options)
{
}
public virtual DbSet<Department> Departments { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(ConfigurationManager.ConnectionStrings["SIMContext"].ConnectionString);
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.ApplyConfiguration(new DepartmentConfiguration());
}
}
这是我的 IUnitOfWork:
public interface IUnitOfWork : IDisposable
{
IDepartmentRepository Departments { get; }
int Complete();
}
这是 UnitOfWork:
public class UnitOfWork : IUnitOfWork
{
private readonly SIMContext _context;
public UnitOfWork(SIMContext context)
{
_context = context;
Departments = new DepartmentRepository(_context);
}
public IDepartmentRepository Departments { get; private set; }
public int Complete()
{
return _context.SaveChanges();
}
private bool disposed = false;
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
_context.Dispose();
}
}
this.disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
这是我的 IRepository:
public interface IRepository<TEntity> where TEntity : class
{
Task<TEntity> GetByIdAsync(object id);
Task<IEnumerable<TEntity>> GetAllAsync();
Task<TEntity> FindAsync(Expression<Func<TEntity, bool>> predicate, string[] includes = null);
Task<IEnumerable<TEntity>> FindAllAsync(Expression<Func<TEntity, bool>> predicate, string[] includes = null);
Task<IEnumerable<TEntity>> FindAllAsync(Expression<Func<TEntity, bool>> predicate, int take, int skip);
Task<TEntity> SingleOrDefault(Expression<Func<TEntity, bool>> predicate);
Task<TEntity> AddAsync(TEntity entity);
Task<IEnumerable<TEntity>> AddRangeAsync(IEnumerable<TEntity> entities);
void Remove(TEntity entity);
void RemoveRange(IEnumerable<TEntity> entities);
}
这是我的存储库:
public class Repository<TEntity> : IRepository<TEntity> where TEntity : class
{
protected readonly DbContext Context;
internal DbSet<TEntity> dbSet;
public Repository(DbContext context)
{
Context = context;
dbSet = Context.Set<TEntity>();
}
public async Task<TEntity> AddAsync(TEntity entity)
{
await dbSet.AddAsync(entity);
return entity;
}
public async Task<IEnumerable<TEntity>> AddRangeAsync(IEnumerable<TEntity> entities)
{
await dbSet.AddRangeAsync(entities);
return entities;
}
public async Task<TEntity> FindAsync(Expression<Func<TEntity, bool>> predicate, string[] includes = null)
{
IQueryable<TEntity> query = dbSet;
if (includes != null)
foreach (var incluse in includes)
query = query.Include(incluse);
return await query.SingleOrDefaultAsync(predicate);
}
public async Task<IEnumerable<TEntity>> FindAllAsync(Expression<Func<TEntity, bool>> predicate, string[] includes = null)
{
IQueryable<TEntity> query = dbSet;
if (includes != null)
foreach (var include in includes)
query = query.Include(include);
return await query.Where(predicate).ToListAsync();
}
public async Task<IEnumerable<TEntity>> FindAllAsync(Expression<Func<TEntity, bool>> predicate, int take, int skip)
{
return await dbSet.Where(predicate).Skip(skip).Take(take).ToListAsync();
}
public async Task<TEntity> GetByIdAsync(object id)
{
return await dbSet.FindAsync(id);
}
public async Task<IEnumerable<TEntity>> GetAllAsync()
{
return await dbSet.ToListAsync();
}
public void Remove(TEntity entity)
{
dbSet.Remove(entity);
}
public void RemoveRange(IEnumerable<TEntity> entities)
{
dbSet.RemoveRange(entities);
}
public async Task<TEntity> SingleOrDefault(Expression<Func<TEntity, bool>> predicate)
{
return await dbSet.SingleOrDefaultAsync(predicate);
}
}
这是 IDepartmentRepository :
public interface IDepartmentRepository: IRepository<Department>
{
}
这是 DepartmentRepository :
public class DepartmentRepository : Repository<Department>, IDepartmentRepository
{
public DepartmentRepository(SIMContext context) : base(context)
{
}
public SIMContext SIMContext
{
get { return Context as SIMContext; }
}
}
这是我的程序 class :
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
public static IContainer Container;
[STAThread]
static void Main()
{
DevExpress.UserSkins.BonusSkins.Register();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Container = Configure();
Application.Run(new XtraMain(Container.Resolve<IUnitOfWork>()));
}
static IContainer Configure()
{
var builder = new ContainerBuilder();
builder.RegisterType<UnitOfWork>().As<IUnitOfWork>();
builder.RegisterType<XtraMain>();
return builder.Build();
}
}
这是我的 XtraMain 表单:
private readonly IUnitOfWork unitOfWork;
public XtraMain(IUnitOfWork unitOfWork)
{
InitializeComponent();
this.unitOfWork = unitOfWork;
}
private void bbtnDepartment_ItemClick(object sender, ItemClickEventArgs e)
{
Frm_Department frme = new(unitOfWork)
{
Name = "Frm_Department"
};
ViewChildForm(frme);
}
但是当我 运行 程序时,我在这一行出现错误:
Application.Run(new XtraMain(Container.Resolve<IUnitOfWork>()));
错误是:
Autofac.Core.DependencyResolutionException HResult=0x80131500 Message=An exception was thrown while activating Smart_Industrial_Management.Persistence.UnitOfWork. Source=Autofac StackTrace: at Autofac.Core.Resolving.Middleware.ActivatorErrorHandlingMiddleware.Execute(ResolveRequestContext context, Action
1 next) at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext ctxt) at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext ctxt) at Autofac.Core.Resolving.Middleware.SharingMiddleware.Execute(ResolveRequestContext context, Action
1 next) at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.b__1(ResolveRequestContext ctxt) at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.b__1(ResolveRequestContext ctxt) at Autofac.Core.Resolving.Middleware.CircularDependencyDetectorMiddleware.Execute(ResolveRequestContext context, Action1 next) at Autofac.Core.Resolving.Pipeline.ResolvePipelineBuilder.<>c__DisplayClass14_0.<BuildPipeline>b__1(ResolveRequestContext ctxt) at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, ResolveRequest request) at Autofac.Core.Resolving.ResolveOperation.ExecuteOperation(ResolveRequest request) at Autofac.Core.Lifetime.LifetimeScope.ResolveComponent(ResolveRequest request) at Autofac.ResolutionExtensions.TryResolveService(IComponentContext context, Service service, IEnumerable
1 parameters, Object& instance) at Autofac.ResolutionExtensions.ResolveService(IComponentContext context, Service service, IEnumerable1 parameters) at Autofac.ResolutionExtensions.Resolve[TService](IComponentContext context, IEnumerable
1 parameters) at Smart_Industrial_Management.Program.Main() in C:\Users\MBoua\source\repos\SIM Windows7 EF Core5\Smart Industrial Management\Program.cs:line 49 This exception was originally thrown at this call stack: [External Code] Inner Exception 1: DependencyResolutionException: None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'Smart_Industrial_Management.Persistence.UnitOfWork' can be invoked with the available services and parameters: Cannot resolve parameter 'Smart_Industrial_Management.Persistence.SIMContext context' of constructor 'Void .ctor(Smart_Industrial_Management.Persistence.SIMContext)'.
我该如何解决这个问题?
DependencyResolutionException: None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'Smart_Industrial_Management.Persistence.UnitOfWork' can be invoked with the available services and parameters: Cannot resolve parameter 'Smart_Industrial_Management.Persistence.SIMContext context' of constructor 'Void .ctor(Smart_Industrial_Management.Persistence.SIMContext)'.
您似乎在配置 Autofac 时没有注册 SIMContext
。在您的 Configure
方法中添加以下注册可能会有所帮助:
builder.RegisterType<SIMContext>().AsSelf();