如何将依赖项注入到实现接口的类中?

2024-04-13

我知道接口不能定义构造函数。强制所有类实现接口并以统一契约接收其依赖项的最佳实践是什么。我知道整数可以通过属性将依赖项注入到对象中,但通过构造函数传递它们对我来说更有意义。那么如何DI呢?


我知道你说过你想要一份稳定的合同。但有一个优势not提供稳定的接口的问题是,您的依赖关系可能会随着不同的实现而发生很大的变化,这将减少耦合:

public interface IBlogRepository
{
    IEnumerable<Entry> GetEntries(int pageId, int pageCount);
}

class BlogDatabase : IBlogRepository
{
    public BlogDatabase(ISession session)
    {
        this.session = session;
    }

    public IEnumerable<Entry> GetEntries(int pageId, int pageCount)
    {
        // Not that you should implement your queries this way...
        var query = session.CreateQuery("from BlogEntry");
        return query.Skip(pageId * pageCount).Take(pageCount);
    }

    private ISession session;
}

正如您所说,您还可以将依赖项实现为属性(或参数),但这将对您的依赖项进行硬编码,而不是使它们特定于实现。您将解耦特定的会话实现,但您仍然必须依赖于会话。

public interface IBlogRepository
{
    ISession Session { get; set; }
    IEnumerable<Entry> GetEntries(int pageId, int pageCount);
    IEnumerable<Entry> GetEntriesWithSession(ISession session,
        int pageId, int pageCount);
}

class BlogDatabase : IBlogRepository
{
    public ISession Session { Get; set; }

    public IEnumerable<Entry> GetEntries(int pageId, int pageCount)
    {
        var query = Session.CreateQuery ...
    }

    public IEnumerable<Entry> GetEntries(ISession session, int pageId, int pageCount)
    {
        var query = session.CreateQuery ...
    }
}

class BlogFile : IBlogRepository
{
    // ISession has to abstract a file handle.  We're still okay
    // ...
}

class BlogInMemory : IBlogRepository
{
    // ISession abstracts nothing.
    // Maybe a lock, at best, but the abstraction is still breaking down
    // ...
}

仅当您使用某种可以为您处理构建/提供依赖项的依赖项注入框架时,构造函数注入才会起作用。即使没有框架,属性和参数注入也可以工作。

我相信这三个都是公认的做法。至少有几个流行的框架支持构造函数和属性注入。

这意味着什么对您的项目最有意义由您决定。权衡是易于跟踪的依赖图与更强的耦合。该决定当然也不必是全构造函数或全属性/参数。

另一个需要考虑的高级抽象是抽象工厂类。如果您想要对一组依赖项进行分组,或者需要在运行时构造它们的实例,则可以这样做:

public interface IInstallationFactory
{
    IUser CreateRegisteredUser(Guid userSid);
    IPackage CreateKnownPackage(Guid id);
    IInstaller CreateInstaller();
}

各种框架也支持抽象工厂。

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

如何将依赖项注入到实现接口的类中? 的相关文章

随机推荐

  • Selenium C# 中的显式等待不起作用。怎么了?

    所以我遇到了显式等待的问题 我不想使用 Thread Sleep 这是一个简单的测试 它打开一个页面 然后后退和前进 加载此页面大约需要 2 3 秒 我想以动态方式执行此操作 测试 希望我不要太困惑 我做了很多研究 但没有任何作用 也许我做
  • Delphi从ios/Android本地存储打开PDF

    我尝试在移动设备上从本地存储打开 PDF 文件 我已将文件放入 iOS 的启动 文档 Android 的资产 内部 用这个代码 filename TPath Combine TPath GetDocumentsPath file pdf W
  • 记忆 SQL 查询

    假设我有一个运行 SQL 查询并返回数据帧的函数 import pandas io sql as psql import sqlalchemy query string select a from table def run my quer
  • Groovy 字符串连接

    当前代码 row column each column gt println column attributes name println column value Column is a Node具有单个属性和单个值 我正在解析 xml
  • iOS13:如何检测状态栏点击事件?

    在我的 appDelegate 中 我覆盖touchesBegan检测何时单击状态栏 void touchesBegan NSSet touches withEvent UIEvent event super touchesBegan to
  • 将 PUT/POST/DELETE 与 JSONP 和 jQuery 结合使用

    我正在致力于创建一个支持跨域请求 JSON JSONP 支持和主要 HTTP 方法 PUT GET POST DELETE 的 RESTful API 现在 虽然通过服务器端代码可以轻松访问此 API 但最好将其公开给 JavaScript
  • Spring云任务-worker pod在kubernetes中没有被删除

    我们正在使用基于 spring cloud deployer kubernetes 的 Spring Batch 远程分区 由于某种原因 Worker pod 在 Worker 执行后没有被删除 想知道通过 TaskLauncher 启动清
  • #Meteor 中带有 blaze 的数组中的每个字符串

    我有一个用户名数组 在列表中呈现 如下所示 each contacts div class name this div each 这工作得很好 但后来我尝试从事件中获取用户名 click name function e t console
  • 随机化表格单元格

    我知道它听起来有点有线 但是有什么方法可以随机化表格内容吗 正是细胞 这样做的目的 我有一个由多个 xml 生成的表 每个 xml 至少包含 5 个项目 在主表中 我只能按原样订购它们 但我需要随机化这些项目 例如 jsfiddle net
  • 为什么我无法在 Firefox 中提交动态创建的表单

    我复制了我正在开发的一个更大项目的一部分 我没有编写代码 所以我希望有人能帮助我找出为什么用这种方式从 js 代码发送 post 请求在 IE 中有效 而在其他中无效浏览器 function f var container document
  • 生成两个浮点数之间的随机浮点数

    我知道这是一个相当简单的问题 但我的数学不太好 我知道如何生成 0 到 1 之间的随机浮点数 float random float rand float RAND MAX 但是 如果我想要一个给定两个浮点数范围的函数 返回该范围内的伪随机浮
  • Volley 以 utf-8 格式发送请求

    我正在通过以下方式向网络发送请求volleyandroid 上的库包含一些ArabicURL中的字符 但是在php文件中我得到了问号而不是阿拉伯字母 我尝试了人们在网上所说的解决方案 但所有这些都尝试从网络读取数据as UTF 8 不以 U
  • 如何在 grails 3 中运行单个集成测试?

    Grails 3 至少 3 1 10 在仅运行特定测试时不稳定 如何让它运行单个集成测试 这是运行单个集成测试的示例命令 grails test app LoginFunctional integration 如果将 integration
  • 使用 MongoMapper 查询不同值

    我该如何查询distinct与 MongoMapper 一起使用吗 我的查询是 subscribedToThread Comment where subscribe thread gt 1 all 但这会返回许多具有相同属性的对象user
  • iOS下逐帧读取视频

    我正在寻找一种使用 iOS API 检索视频各个帧的方法 我尝试使用 AVAssetImageGenerator 但它似乎只提供最接近秒的帧 这对我的使用来说有点太粗糙了 根据我对文档的理解 AVAssetReader AVAssetRea
  • 寻找 JS/JQuery 完全模态覆盖 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我需要一个模态叠加层 它将阻止与页面其余部分的交互 并且用户无法关闭 但似乎找不到一个不需要覆盖现有功
  • 为什么我能够访问java中没有对象的方法[重复]

    这个问题在这里已经有答案了 这是我的代码 public class MyProjectPage extends AbstractPage public boolean addDefaultProjectBymyProjects String
  • 当 var 应该有一个值时,“TypeError:无法将 'NoneType' 对象隐式转换为 str”

    import sys from tkinter import def print print Encoded message with offset gui Tk gui title Caesar Cypher Encoder Button
  • 如何在 IntelliJ IDEA 中使用 Scala(或者:为什么为 Scala 找到一个可用的 IDE 如此困难)?

    我最近放弃了在 Eclipse 中使用 Scala 的尝试 像完成这样的基本功能不起作用 所以现在我正在尝试 IntelliJ 我还没有走多远 我已经能够编辑程序 在语法突出显示和完成内 耶 但我什至无法运行最简单的 Hello World
  • 如何将依赖项注入到实现接口的类中?

    我知道接口不能定义构造函数 强制所有类实现接口并以统一契约接收其依赖项的最佳实践是什么 我知道整数可以通过属性将依赖项注入到对象中 但通过构造函数传递它们对我来说更有意义 那么如何DI呢 我知道你说过你想要一份稳定的合同 但有一个优势not