C# .NET核心(MYSQL)通用存储库使用Autofac自动连接
我的目标是实现以下目标。我正在尝试使用MySQL、.NET Core、Autofac、EF Core设置一个新的解决方案。。。使用(通用)存储库模式 最终,我将跳转到一个现有db的项目上,因此我的目标是以某种方式利用(t4)模板和EF生成一些模型,然后它“应该”(著名的最后一句话)就像为我需要交互的每个模型进行回购一样简单。(每个repo将只是一个继承基础的小型轻量级类) Startup.csC# .NET核心(MYSQL)通用存储库使用Autofac自动连接,c#,.net-core,autofac,ioc-container,entity-framework-core,C#,.net Core,Autofac,Ioc Container,Entity Framework Core,我的目标是实现以下目标。我正在尝试使用MySQL、.NET Core、Autofac、EF Core设置一个新的解决方案。。。使用(通用)存储库模式 最终,我将跳转到一个现有db的项目上,因此我的目标是以某种方式利用(t4)模板和EF生成一些模型,然后它“应该”(著名的最后一句话)就像为我需要交互的每个模型进行回购一样简单。(每个repo将只是一个继承基础的小型轻量级类) Startup.cs public class Startup { public Startup(IHostingE
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();
}
}
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;
}
}
// 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;
}
}
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的适当文档,我有点直觉地感觉到这一部分正在“工作”。但正如您在下面的错误日志中所看到的,我对存储库的注册搞砸了
错误:
激活特定注册时发生错误
有关详细信息,请参见内部异常
注册:Activator=FooService(ReflectionActivator),Services
=[MyApp.Services.Interfaces.IFooService,MyApp.Services.Interfaces.IService],生存期=
Autofac.Core.Lifetime.CurrentScopeLifetime,共享=共享,
所有权=由IfeTimeScope拥有
--->未找到类型为“Autofac.Core.Activators.Reflection.DefaultConstructorFinder”的构造函数
“MyApp.Services.FooService”可以使用可用的
服务和参数:
无法解析参数“MyApp.Data.Interfaces.IFooRepository”
“构造函数”的存储库无效
.ctor(MyApp.Data.Interfaces.IFooRepository)”。(参见内部异常)
详情请参阅。)
-->Autofac.Core.DependencyResolutionException:未找到具有
类型上的“Autofac.Core.Activators.Reflection.DefaultConstructorFinder”
“MyApp.Services.FooService”可以使用可用的
服务和参数:
无法解析参数“MyApp.Data.Interfaces.IFooRepository”
“构造函数”的存储库无效
.ctor(MyApp.Data.Interfaces.IFooRepository)”
以下行将在Autofac中将
存储库注册为IRepository
:
另一个解决方案是注册IRepository
public class FooService: IFooService
{
private readonly IRepository<Foo> _repository;
public FooService(IRepository<Foo> repository)
{
this._repository = repository;
}
// ...
}
顺便说一句,在使用IIS时要小心程序集扫描:尝试删除MyContext的构造函数,看看代码是否正确执行和解析。我看到的问题是ctor的Void.ctor(MyApp.Data),它为我指明了一个方向,即由于ctor和foosrepository,您的FooService无法被实例化。
builder.RegisterType<FooRepository>()
.As<IFooRepository>()
builder.RegisterAssemblyTypes(AppDomain.CurrentDomain.GetAssemblies())
.AsClosedTypesOf(typeof(IRepository<>))
public class FooService: IFooService
{
private readonly IRepository<Foo> _repository;
public FooService(IRepository<Foo> repository)
{
this._repository = repository;
}
// ...
}