DI和存储库模式 [英] DI and repository pattern
问题描述
目前,我的代码与此类似(仅缩短了一点):
Currently, my code is similar to this (shortened just to make a point):
存储库界面
public interface IRepository<TEntity, in TKey>
{
IList<TEntity> GetAll();
TEntity Get(TKey id);
TEntity Add(TEntity item);
TEntity Update(TEntity item);
bool Remove(TKey id);
}
基本EF存储库
public class BaseEFRepository<TEntity, TKey> : IRepository<TEntity, TKey> where TEntity: class, IEntity<TKey> where TKey: struct
{
protected readonly DbContext _dbContext;
public BaseRepository()
{
_dbContext = new MyDB();
_dbContext.Configuration.ProxyCreationEnabled = false;
_dbContext.Configuration.LazyLoadingEnabled = false;
}
public virtual TEntity Get(TKey id)
{
return _dbContext.Set<TEntity>().Find(id);
}
public virtual IList<TEntity> GetAll()
{
return _dbContext.Set<TEntity>()
.ToList();
}
public virtual TEntity Add(TEntity item)
{
_dbContext.Set<TEntity>().Add(item);
_dbContext.SaveChanges();
return item;
}
.....
.....
}
基础存储库的示例实现
public interface IContactsRepository : IRepository<Contact, long>
{
Contact GetByEmployeeId(string empId, ContactType type);
IList<Contact> GetByEmployeeId(string empId);
}
public class ContactsRepository : BaseEFRepository<Contact, long>, IContactsRepository
{
public Contact GetByEmployeeId(string empId, ContactType type)
{
var contact = _dbContext.Set<Contact>()
.FirstOrDefault(d => d.EmployeeId == empId && d.ContactType == type);
return contact;
}
public IList<Contact> GetByEmployeeId(string empId)
{
var contacts = _dbContext.Set<Contact>()
.Where(d => d.EmployeeId == empId)
.ToList();
return contacts;
}
}
BLL
BLL
public class Contacts
{
public Contact Get(long id)
{
IContactsRepository repo = ResolveRepository<IContactsRepository>();
var contact = repo.Get(id);
return contact;
}
public Contact GetByEmployeeId(string empId, ContactType type)
{
IContactsRepository repo = ResolveRepository<IContactsRepository>();
return repo.GetByEmployeeId(empId, type);
}
.......
.......
}
现在,一切都很好。我可以这样做:
Now, everything is fine. I can simply do something like this:
var _contacts = new Contacts();
var contact = _contacts.GetByEmployeeId("C1112", ContactType.Emergency);
当我阅读这个博文,作者说使用如下代码: p>
The confusion started when I read this blog post, the author says that using code like:
IContactsRepository repo = ResolveRepository<IContactsRepository>();
是一种不好的技术,它是反模式,应该将所有内容注入到代码的根目录中。我看不到如何使用存储库模式来执行此操作。我正在使用WCF使用它。那么,如何从WCF中的第一个调用注入一切呢?我无法得到它我在这里缺少什么?
is a bad technique and it's anti-pattern and one should inject everything at the root of code. I can't see how would I do this with repository pattern. I am consuming this using a WCF. So, how on earth would I inject everything from the first call in WCF? I can't get it. What am I missing here?
最后一件事,在这种情况下,WCF是最后一层,它应该只知道它之前的层, BLL层。如果我要执行任何作为该博客的作者建议,我将使WCF层意识到DAL层,不是那么糟糕的做法?如果我错了,请纠正我。
One last thing, in this case the WCF is the last layer, and it should be only aware of the layer before it, which is the BLL layer. If I am going to implement anything as the author of that blog suggested, I will make the WCF layer aware of the DAL layer, isn't that bad practice? correct me if I am wrong.
推荐答案
您需要使用构造函数注入,然后在组合根。
You need to use Constructor Injection and then compose your objects in the Composition Root.
当您使用构造函数注入,您通过构造函数注入依赖关系,因此您的类将如下所示:
When you use Constructor Injection, you inject the dependencies through the constructors, so your classes would look like something like this:
public class BaseRepository
{
protected readonly DbContext _dbContext;
//...
public BaseRepository(DbContext context)
{
_dbContext = context;
}
//...
}
public class ContactsRepository : BaseEFRepository<Contact, long>, IContactsRepository
{
//...
public ContactsRepository(DbContext context)
:base(context)
{
}
//...
}
public class Contacts
{
private readonly IContactsRepository m_ContactsRepository;
public Contacts(IContactsRepository contacts_repository)
{
m_ContactsRepository = contacts_repository;
}
public Contact Get(long id)
{
var contact = m_ContactsRepository.Get(id);
return contact;
}
//...
}
然后在组合根你将组合所有的对象在一起。可选地,通过DI容器。
Then in the Composition Root your would compose all your objects together. Optionally via a DI container.
以下是使用 Pure DI :
var context = new MyDB();
context.Configuration.ProxyCreationEnabled = false;
context.Configuration.LazyLoadingEnabled = false;
var contacts = new Contacts(new ContactsRepository(context));
在IIS中托管的WCF应用程序中,组合根是一个自定义 ServiceHostFactory
。 此答案提供了有关如何执行此操作的更多详细信息。
In a WCF application that is hosted in IIS, the Composition Root is a custom ServiceHostFactory
. This answer provides more details about how to do that.
这篇关于DI和存储库模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!