【发布时间】:2018-01-03 06:32:38
【问题描述】:
我的目标是实现以下目标。我正在尝试使用 MySQL、.NET Core、Autofac、EF Core 设置一个新的解决方案...利用(通用)存储库模式。
最终我会跳到一个有现有数据库的项目,因此我的目标是以某种方式利用 (t4) 模板和 EF 来生成一些模型,然后它“应该”(最后著名话)就像为我需要与之交互的每个模型创建一个 repo 一样简单。 (每个 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();
}
}
(通用)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 的适当文档,而且我有点直觉认为那部分正在“工作”。但正如您在下面的错误日志中看到的那样,我对存储库的注册搞砸了。
错误:
在激活特定注册期间发生错误。
详情请参阅内部异常。
注册:Activator = FooService (ReflectionActivator), Services = [MyApp.Services.Interfaces.IFooService, MyApp.Services.Interfaces.IService], 生命周期 = Autofac.Core.Lifetime.CurrentScopeLifetime,共享 = 共享, 所有权 = OwnedByLifetimeScope
---> 没有找到类型为 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' 的构造函数 'MyApp.Services.FooService' 可以用可用的调用 服务和参数:
无法解析参数'MyApp.Data.Interfaces.IFooRepository 构造函数 'Void 的存储库' .ctor(MyApp.Data.Interfaces.IFooRepository)'。 (见内部异常 详情。)
--> Autofac.Core.DependencyResolutionException: 没有找到任何构造函数 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' 类型 'MyApp.Services.FooService' 可以用可用的调用 服务和参数:
无法解析参数'MyApp.Data.Interfaces.IFooRepository 构造函数 'Void 的存储库' .ctor(MyApp.Data.Interfaces.IFooRepository)'。
【问题讨论】:
-
尝试删除有关 MyContext 的构造函数,看看您的代码是否正确执行和解析。我看到的问题是 ctor 'Void .ctor(MyApp.Data),这为我指明了您的 FooService 无法实例化的方向,因为分别是 ctor 和 FooRepository。
标签: c# .net-core autofac ioc-container entity-framework-core