c# – 使用Autofac的.NET Core(MYSQL)通用存储库自动连接
我的目标是以下内容.我正在尝试使用以下方法设置新的解决方案:
MySQL,.NET Core,Autofac,EF Core ……利用(通用)存储库模式.
Startup.cs public class Startup { public Startup(IHostingEnvironment env) { var builder = new ConfigurationBuilder() .SetBasePath(env.ContentRootPath) .AddJsonFile("appsettings.json",optional: true,reloadOnChange: true) .AddJsonFile($"appsettings.{env.EnvironmentName}.json",optional: true) .AddEnvironmentVariables(); this.Configuration = builder.Build(); } public IConfigurationRoot Configuration { get; private set; } // This method gets called by the runtime. // Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddMvc(); services. .AddDbContext<MyContext>(o => o.UseMySQL( Configuration.GetConnectionString("MyConnection"))); } public void ConfigureContainer(ContainerBuilder builder) { builder.RegisterGeneric(typeof(Repository<>)) .As(typeof(IRepository<>)) .InstancePerLifetimeScope(); // the below works (before adding the repos) builder.RegisterAssemblyTypes(AppDomain.CurrentDomain.GetAssemblies()) .AssignableTo<IService>() .AsImplementedInterfaces() .InstancePerLifetimeScope(); } } (Generic)Repository.cs public abstract class Repository<T> : IRepository<T> where T : class { private readonly MyContext _context; protected Repository(MyContext context) { _context = context; } public virtual string Add(T entity) { if (ValidateAdd(ref entity,out var message)) { _context.Set<T>().Add(entity); } return message; } public virtual bool ValidateAdd(ref T entity,out string message) { message = default(string); return true; } } 存储库的实现: FooRepository.cs // public interface IFooRepository: IRepository<Foo> public class FooRepository: Repository<Foo>,IFooRepository { public FooRepository(MyContext context) : base(context) { } public override bool ValidateAdd(ref Foo entity,out string message) { // just a hook for pre-insert stuff message = "All foos shall fail add"; return false; } } 然后在服务或控制器中使用,或者你有什么. FooService.cs public class FooService: IFooService { private readonly IFooRepository _repository; public FooService(IFooRepository repository) { _repository = repository; } public void DoSomethingThenAdd() { // some other business logic specific to this service _repository.Add(new Foo() { Id = 1,LastName = "Bar",Name = "Foo" }); } } 问题: 我如何解决所有这些问题……我一直在努力寻找关于MySQL Ef的正确文档,而且我有点觉得那部分是“正常工作”.但正如您在下面的错误日志中所看到的那样,我对存储库的注册搞砸了. 错误:
解决方法
以下行将注册Repository< Foo>作为IRepository< Foo>在Autofac中:
builder.RegisterGeneric(typeof(Repository<>)) .As(typeof(IRepository<>)) .InstancePerLifetimeScope(); 但是IRepository< Foo>不是IFooRepository,FooService需要IFooRepository.这就是为什么Autofac失败并出现以下错误消息:
如果你想保留你的FooRepository和IFooRepository,你必须注册它们: builder.RegisterType<FooRepository>() .As<IFooRepository>() 另一种解决方案是注册IRepository<>的所有实现. builder.RegisterAssemblyTypes(AppDomain.CurrentDomain.GetAssemblies()) .AsClosedTypesOf(typeof(IRepository<>)) 和FooService应该依赖于Irepository< Foo>而不是IFooRepository public class FooService: IFooService { private readonly IRepository<Foo> _repository; public FooService(IRepository<Foo> repository) { this._repository = repository; } // ... } 当您使用IIS:Assembly scanning – IIS Hosted application时,请小心使用程序集扫描 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |