我正在编写一个程序,将StructureMap用作IOC容器。
我已经实现了几个接口 - IUnitOfWork
和IDataAccessRepository
,这些接口在运行时使用以下类(在他们自己的项目中{ - 1}})解析。
EntityFrameworkRepository.cs
CardGame.EntityFrameworkProvider
EntityFrameworkUnitofWork.cs
public class EntityFrameworkRepository<T> : IDataAccessRepository<T>
where T : class
{
private DbContext _ctx;
private DbSet<T> set;
internal EntityFrameworkRepository(DbContext ctx)
{
_ctx = ctx;
set = _ctx.Set<T>();
}
public IEnumerable<T> Elements
{
get { return set; }
}
public T Get(int id)
{
return set.Find(id);
}
public void Add(T t)
{
set.Add(t);
}
public void Update(T t)
{
set.Attach(t);
_ctx.Entry<T>(t).State = EntityState.Modified;
}
public void Delete(T t)
{
if (_ctx.Entry<T>(t).State == EntityState.Detached)
set.Attach(t);
set.Remove(t);
}
}
最后,在我的main方法中 - 在另一个项目中 - 我使用StructureMap将依赖项绑定在一起。 主要
public class EntityFrameworkUnitOfWork : DbContext, IUnitOfWork
{
/// <summary>
/// Creates an EntityFrameworkUnitOfWork.
/// </summary>
/// <param name="connectionStringOrName"></param>
public EntityFrameworkUnitOfWork(string connectionStringOrName) : base(connectionStringOrName)
{
Database.SetInitializer<EntityFrameworkUnitOfWork>(new DropCreateDatabaseIfModelChanges<EntityFrameworkUnitOfWork>());
Creatures = new EntityFrameworkRepository<Models.Cards.Creature>(this);
MagicCards = new EntityFrameworkRepository<Models.Cards.Magic>(this);
EffectDescriptors = new EntityFrameworkRepository<Models.Effects.EffectDescriptor>(this);
}
#region Repositories
public IDataAccessRepository<Models.Cards.Creature> Creatures
{
get;
private set;
}
public IDataAccessRepository<Models.Cards.Magic> MagicCards
{
get;
private set;
}
public IDataAccessRepository<Models.Effects.EffectDescriptor> EffectDescriptors
{
get;
private set;
}
#endregion
public new void SaveChanges()
{
base.SaveChanges();
}
}
我的问题是, ObjectFactory.Configure(x =>
{
x.Scan(scan =>
{
scan.LookForRegistries();
scan.Assembly("CardGame.DataAccess");
scan.Assembly("CardGame.EntityFrameworkProvider");
});
#region Persistence
x.For<CardGame.DataAccess.IUnitOfWork>().Use(new CardGame.EntityFrameworkProvider.EntityFrameworkUnitOfWork("MyConnectionString"));
#endregion
});
扩展EntityFrameworkUnitOfWork
,我的DbContext
(包含Main.cs的项目)无法编译,因为它没有(故意)包含对EntityFramework的引用。我试图尽可能地将其作为数据库不可知,并且到目前为止它已经很顺利,但是当我CardGame.Server
延长EntityFrameworkUnitOfWork
时(因此我可以应用DbContext
初始值设定项),整个事情都爆炸了。
我DropCreateDatabaseIfNotExists
扩展EntityFrameworkUnitOfWork
的原因主要是因为DbContext
包含IUnitOfWork
(或其他提供商)需要实施的所有存储库。我最初没有这样做,但我推断我从模型中删除DAL,而不是从DAL中删除模型 - 并且在EntityFrameworkUnitOfWork
对象上获取属性来获取存储库会更容易需要的。
你有什么建议吗?
添加对EntityFramework 的引用确实解决了问题,但这也意味着我必须在我的主项目中根本不使用它时添加对EntityFramework的引用!
编辑:更新!我设法让它工作,但只是通过向我的项目添加EntityFramework引用。我创建了一个名为IUnitOfWork
的新类,其中包含EntityFrameworkContext
,这是在创建DbSet<T>
时创建的(在其静态构造函数中有一个初始化器)。我想这个问题归结为:
假设EF层的项目是项目A. 注入了层的项目是项目B.
如何在项目A上设置EntityFramework设置(可能在它的App.config中),以便项目B在其配置中不需要对EntityFramework的引用? 整个想法是该层应该可以与其他项目交换(比如NHibernate或ActiveRecord),我不需要修改我的主项目来占用这些修改。此外,项目A根本没有直接引用EntityFramework - 它没有任何意义可以引用它。
答案 0 :(得分:1)
如果问题是这一行
x.For<CardGame.DataAccess.IUnitOfWork>().Use(new CardGame.EntityFrameworkProvider.EntityFrameworkUnitOfWork("MyConnectionString"));
然后你应该考虑使用registry。这样,您可以在项目中引用一个注册表,其中引用的EntityFramework类似于:
public class MyProjectRegistry : Registry
{
public MyProjectRegistry()
{
For<CardGame.DataAccess.IUnitOfWork>().Use(new CardGame.EntityFrameworkProvider.EntityFrameworkUnitOfWork("MyConnectionString"));
}
}
由于您的ObjectFactory已经配置为查找注册表,因此这应该足以让它工作。