DI和存储库模式 [英] DI and repository pattern

查看:357
本文介绍了DI和存储库模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前,我的代码与此类似(仅缩短了一点):

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆