我首先使用实体框架代码。我希望能够在实例化从System.Data.Entity.DbContext派生的上下文时注入一个System.Data.Entity.DbContext对象。这样我就可以根据代码运行的环境传递不同类型的连接,即在开发中使用System.Data.SqlClient ( Server),在单元测试时使用System.Data.SQLite,在生产中使用其他东西。Context的相关部分如下所示:
public class Context : DbContext
{
public Context(DbConnection dbConnection)
: base(dbConnection, true)
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
Database.SetInitializer(new MigrateDatabaseToLatestVersion<Context, Configuration>());
base.OnModelCreating(modelBuilder);
}
public DbSet<Test> Tests { get; set; }
}这给了我以下错误:The target context 'Services.Persistence.Context' is not constructible. Add a default constructor or provide an implementation of IDbContextFactory.,我认为这发生在模型初始化时,实体框架显然认为它需要更新自己的Context,而不依赖于我试图实现的IoC模式。默认构造函数的缺乏是设计造成的。IDbContextFactory接口同样无用--它也必须有一个默认的构造函数。
实体框架代码首先完全遵循通过从配置文件读取连接字符串(或者直接传递连接字符串)来设置它的配置的想法,还是能够解决这个问题?
更新,这里是温莎配置:
container.Register(Component
.For<DbConnection>()
.UsingFactoryMethod(() =>
new SqlConnection("Data Source=(localdb)\\v11.0;Database=ThatProject;MultipleActiveResultSets=true"))
.LifeStyle.Transient);
container.Register(Component
.For<Context>()
.UsingFactoryMethod(k => new Context(k.Resolve<DbConnection>()))
.LifeStyle.PerWebRequest);
container.Register(Component
.For<IRepository>()
.UsingFactoryMethod(k => new Repository(k.Resolve<Context>()))
.LifeStyle.PerWebRequest);发布于 2012-10-01 05:50:28
我很确定你的问题与EF无关,但我不是温莎的用户,所以我不能确切地告诉你你的配置问题是什么。我所做的是复制一个类似的配置,它的工作方式与您所期望的完全一样,请参见下面的内容:
class Program
{
static void Main(string[] args)
{
IKernel kernel = new StandardKernel();
kernel.Bind<DbConnection>().ToMethod((ctx) =>{return new SqlConnection("Data Source=(localdb)\\v11.0;Database=ThatProject;MultipleActiveResultSets=true");});
kernel.Bind<Context>().ToSelf();//not really needed
kernel.Bind<TestRepository>().ToSelf();//not really needed
kernel.Get<TestRepository>();
}
}
public class Context : DbContext
{
public Context(DbConnection dbConnection)
: base(dbConnection, true){}
public DbSet<Test> Tests { get; set; }
}
public class TestRepository
{
public TestRepository(Context c)
{
c.Tests.Add(new Test());
c.SaveChanges();
var all = c.Tests;
}
}
public class Test
{
public int Id { get; set; }
}这意味着EF并不试图对上下文创建做任何有趣的事情(因为一个非空的构造函数对我来说很好)。
从温莎配置中,我希望您需要执行如下操作,但是,我不太确定确切的语法:
container.Register(Component
.For<DbConnection>()
.UsingFactoryMethod(() =>
new SqlConnection("Data Source=(localdb)\\v11.0;Database=ThatProject;MultipleActiveResultSets=true"))
.LifeStyle.Transient);
container.Register(Component
.For<Context>()
.ImplementedBySelf()//this probably isn't the correct syntax
.LifeStyle.PerWebRequest);//per request is good, i have some details around why this is good practice if you are interested
container.Register(Component
.For<IRepository>()
.ImplementedBy<ConcreteRepository>()//you arent really calling a method and creating the object yourself you are letting Windsor create the object and sort out the dependancy tree
.LifeStyle.PerWebRequest);https://stackoverflow.com/questions/12664636
复制相似问题