C# .NET核心(MYSQL)通用存储库使用Autofac自动连接

C# .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

我的目标是实现以下目标。我正在尝试使用MySQL、.NET Core、Autofac、EF Core设置一个新的解决方案。。。使用(通用)存储库模式

最终,我将跳转到一个现有db的项目上,因此我的目标是以某种方式利用(t4)模板和EF生成一些模型,然后它“应该”(著名的最后一句话)就像为我需要交互的每个模型进行回购一样简单。(每个repo将只是一个继承基础的小型轻量级类)

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();
    }
}
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;
    }

    // ...
}