DI 和存储库模式

2024-03-18

目前,我的代码与此类似(为了说明一点而缩短):

DAL

存储库接口

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

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);
    }
    .......
    .......
}

现在,一切都很好。我可以简单地做这样的事情:

 var _contacts = new Contacts();
 var contact = _contacts.GetByEmployeeId("C1112", ContactType.Emergency);

当我阅读时,困惑开始了这篇博文 http://www.devtrends.co.uk/blog/how-not-to-do-dependency-injection-the-static-or-singleton-container,作者说使用如下代码:

IContactsRepository repo = ResolveRepository<IContactsRepository>();  

是一种糟糕的技术,它是反模式的,应该将所有内容注入代码的根部。我不知道如何使用存储库模式来做到这一点。我正在使用 WCF 来使用它。那么,我到底如何从 WCF 中的第一次调用中注入所有内容呢?我听不懂。我在这里缺少什么?

最后一件事,在这种情况下,WCF 是最后一层,它应该只知道它之前的层,即 BLL 层。如果我要按照该博客作者的建议实现任何内容,我将使 WCF 层了解 DAL 层,这不是不好的做法吗?如果我错了请纠正我。


您需要使用构造函数注入,然后在成分根 http://blog.ploeh.dk/2011/07/28/CompositionRoot/.

当您使用构造函数注入时,您通过构造函数注入依赖项,因此您的类将如下所示:

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 容器。

这是使用此类组合的示例Pure DI http://blog.ploeh.dk/2014/06/10/pure-di/:

var context = new MyDB();

context.Configuration.ProxyCreationEnabled = false;

context.Configuration.LazyLoadingEnabled = false;

var contacts = new Contacts(new ContactsRepository(context));

在 IIS 中托管的 WCF 应用程序中,组合根是自定义的ServiceHostFactory. 这个答案 https://stackoverflow.com/a/2455039/2290059提供了有关如何执行此操作的更多详细信息。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

DI 和存储库模式 的相关文章

随机推荐

  • 如何从我的 iOS 应用程序向 Mac 应用程序发送 MIDI 或 OSC 信号?

    我正在考虑编写一个 iPhone iPad 应用程序来模拟 MIDI 控制器 我知道已经有很多可用的 但我仍然想自己做 我对此有几个问题 我对 MIDI 了解一点 但最近听说了 OSC 显然 几乎所有 DJ 软件应用程序都支持 MIDI 但
  • ActionFilter 和 ResultFilter 的不同和示例

    我无法理解 ActionFilter 和 ResultFilter 之间的区别 执行OnActionExecuted方法后的ResultFilter 您能否解释一下 ActionFilter 和 ResultFilter 的主要区别和示例
  • 用Java读取纯文本文件

    Java 中读取和写入文件数据的方式似乎有不同 我想从文件中读取 ASCII 数据 有哪些可能的方式以及它们的区别 我最喜欢的读取小文件的方法是使用 BufferedReader 和 StringBuilder 它非常简单明了 虽然不是特别
  • 在常规反应中,如何在提交或“输入”键上关闭移动键盘?

    我试图找到这个答案 但我发现的所有其他问题都是 React Native handleEnter e if e key Enter REMOVE KEYBOARD 我的输入也是文本搜索 所以我希望键盘隐藏 以便用户可以看到出现的结果 e t
  • 在 JasperReport 中创建/传递 Java bean 数据源

    我在 JSF 应用程序中使用 JasperReport 和 ireport 来动态生成报告 这就是我想要实现的目标 我的结构 读为 HashMap ArrayList 包含需要传递到报告的数据 以便在报告中显示相同的数据 我的报告已经包含一
  • 用 C 编写安全标记联合

    假设你正在写一个C struct它代表一顿饭中的一道菜 课程领域之一struct属于类型 enum TP course STARTER MAINCOURSE DESSERT 然后 根据课程的类型 您有一个子类型 enum TP starte
  • React Native StatusBar:深色内容在 Android 上不起作用

    我正在尝试将标题的颜色和状态栏的图标更改为黑色 所以 根据react native状态栏文档 我设置了barStyle to dark content但没有任何改变
  • C99 中的引用传递

    我刚刚读过this http cartan cas suffolk edu oopdocbook opensource passreference html 在C 和C99 中 我们可以绕过 参考 它提供了相同的 性能相当于指针传递 所以我
  • 如何将 Quickbook 桌面应用程序与网站集成

    我是 Quick Book 的新人 现在我正在准备一个管理面板 在线网站 其中我必须与 Quick Book 桌面版本集成 我正在使用 NET C 平台制作这个网站 这里有一些帖子 但我仍然不清楚 简而言之 我的要求是 我们需要发送提供商名
  • javascript 函数在 jquery $(document).ready 块中不起作用

    我正在尝试打电话JavaScript函数从onclick扳机 HTML部分 div class my radio div
  • 如何使用 Sublime Text 运行节点应用程序

    如何使用 Sublime Text 运行节点应用程序 像这样 在sublime中打开app js文件 进入菜单 gt 工具 gt 构建 它 就运行了 就这么简单 Cmd Shift P 搜索 Nodejs Default File Sett
  • 反序列化 MongoDB BSON

    我尝试从查询 MongoDB 实例的 REST 服务获取响应并将响应解析为 Java 对象 Web 服务使用 MIME 类型的 html 返回响应 并用换行符分隔返回的每个记录 尽管我能够调整服务返回的内容 将 BSON 响应转换为 Jav
  • 自动更新数据库Mysql中的库存

    我需要了解数据库中的一件事 我有产品表及其总库存 如图所示 如果有人知道我该怎么做 请分享 谢谢 当提到关系数据库时 您所问的问题在技术上并不是技术意义上的 关系 这种关系就像有一个表引用另一个表的 键 例如将具有客户地址的表与具有客户订单
  • Azure - 启动命令 - 无法访问 jarfile app.jar

    我有一个 Java Spring Boot 应用程序 部署在 Azure Web 服务上 一切正常 我此刻真正想做的是 java jar Dspring profiles active test app jar 我想通过 Azure 云上的
  • 将 msbuild 任务作为 nuget 传送

    我需要你的帮助 我正在开发一个 msbuild 任务 该任务对 msbuild 执行某些操作 我希望我的用户能够下载并安装 nuget 包 安装包后 构建任务将成为构建过程的一部分 我知道如何发布 nuget 包 并且知道如何将自定义目标文
  • C++:受保护的类构造函数

    如果一个类总是要被继承 那么创建构造函数是否有意义protected class Base protected Base class Child protected Base public Child Base Thanks 仅当您不希望客
  • tsql 脚本来查找未被存储过程、视图、函数等使用的表?

    是否有一个 t sql 脚本来找出 sql server 中没有通过存储过程 视图 函数等使用的表 我有一个数据库 有 100 个表 如果不是更多的话 在我删除表之前 我想知道是否有一个脚本可以遍历数据库中的每个对象并告诉我是否有任何表正在
  • 共享互斥体的交替例程

    我有方法a在某个随机时间重复调用 从而触发方法b 它在一段随机时间后完全执行 并且在它自己的线程中 我想确保随后执行a等到b已完成 由当前执行触发a 换句话说 a and b均须交替执行 我尝试使用互斥体和条件变量来执行此操作 如下所示 d
  • pytorch - “conv1d”在哪里实现?

    我想看看 conv1d 模块是如何实现的https pytorch org docs stable modules torch nn modules conv html Conv1d https pytorch org docs stabl
  • DI 和存储库模式

    目前 我的代码与此类似 为了说明一点而缩短 DAL 存储库接口 public interface IRepository