- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在开始一个新的 MVC 项目,并且(几乎)决定尝试一下 Repository Pattern 和 Dependency Injection。筛选变化需要一段时间,但我为我的应用程序提出了以下结构:
最佳答案
是的,我明白你在做什么(或多或少)但是(据我所知)你错过了 a)将契约(Contract)和实现类型分离到他们自己的项目/程序集中和 b)配置的概念DI 容器,即配置哪些实现应用于接口(interface)。
有无限的方法来处理这个问题,所以我给你的是我个人的最佳实践。我已经用这种方式工作了很长时间,并且仍然对它感到满意,所以我认为它值得分享。
一种。总是有项目:MyNamespace.Something
和 MyNamespace.Something.Contracts
一般来说,对于 DI,我有两个程序集:一个用于仅包含接口(interface)的合约,另一个用于实现这些接口(interface)。在您的情况下,我可能有五个程序集:Presentation.dll
, Services.dll
, Services.Contracts.dll
, DataAccess.dll
和 DataAccess.Contracts.dll
.
(另一个有效的选择是将所有契约(Contract)放在一个程序集中,我们称之为 Commons.dll)
显然,DataAccess.dll
引用资料 DataAccess.Contracts.dll
, 作为 DataAccess.dll
中的类实现 DataAccess.Contracts.dll
内部的接口(interface). Services.dll
相同和 Services.Contracts.dll
.
不,去耦部分:Presentation
引用资料 Services.Contracts
和 Data.Contracts
.服务引用 Data.Contracts
.如您所见,不依赖于具体的实现。这就是整个 DI 的内容。如果你决定交换你的数据访问层,你可以交换 DataAccess.dll
而DataAccess.Contracts.dll
保持不变。您的其他程序集都没有直接引用DataAccess.dll,因此没有断开的链接,版本冲突等。如果不清楚,请尝试绘制一点依赖关系图。您会看到,没有箭头指向任何没有 .Contracts
的程序集。以他们的名义。
你能理解这个吗?请问有什么不清楚的地方。
湾。选择如何配置容器
您可以在显式配置(XML 等)、基于属性的配置和基于约定的注册之间进行选择。虽然出于显而易见的原因前者很痛苦,但我是后者的粉丝。我认为它比基于约定的配置更具可读性和易于调试,但这是一个品味问题。
当然,容器类型捆绑了所有依赖项,而您在应用程序架构中已经避免了这些依赖项。为了明确我的意思,请考虑针对您的案例的 XML 配置:它将包含到所有实现程序集的“链接”DataAccess.dll, ...
.尽管如此,这并没有破坏脱钩的想法。很明显,当交换实现程序集时,您需要修改配置。
但是,使用基于属性或约定的配置时,您通常使用您提到的自动发现机制:“在位于 xyz 的所有程序集中搜索”。这确实需要将所有程序集放在应用程序 bin 目录中。它没有任何问题,因为代码需要在某个地方,对吧?
你有什么收获?假设您已经部署了应用程序并决定交换 DataAccess 层。假设您选择了基于约定的 DI 容器配置。你现在可以做的是在VS中打开一个新项目,引用现有的DataAccess.Contracts.dll
并以任何你喜欢的方式实现所有接口(interface),只要你遵循约定。然后构建库,将其命名为 DataAccess.dll
并将其复制并粘贴到原始应用程序的程序文件夹中,替换旧的 DataAccess.dll
.完成后,您已经交换了整个实现,甚至没有注意到任何其他程序集。
我想你应该已经明白了。这确实是一个权衡,使用 IoC 和 DI。我强烈建议您在设计决策时要务实。不要接口(interface)所有东西,它只会变得困惑。自己决定,DI 和 IoC 真正有意义的地方,不要太受社区宗教讨论的影响。尽管如此,如果使用得当,IoC 和 DI 真的非常非常强大!
关于dependency-injection - 如何在 n 层应用程序中使用 MVC5 和 MEF2(基于约定)实现依赖注入(inject)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24217142/
背景: 我最近一直在使用 JPA,我为相当大的关系数据库项目生成持久层的轻松程度给我留下了深刻的印象。 我们公司使用大量非 SQL 数据库,特别是面向列的数据库。我对可能对这些数据库使用 JPA 有一
我已经在我的 maven pom 中添加了这些构建配置,因为我希望将 Apache Solr 依赖项与 Jar 捆绑在一起。否则我得到了 SolarServerException: ClassNotF
interface ITurtle { void Fight(); void EatPizza(); } interface ILeonardo : ITurtle {
我希望可用于 Java 的对象/关系映射 (ORM) 工具之一能够满足这些要求: 使用 JPA 或 native SQL 查询获取大量行并将其作为实体对象返回。 允许在行(实体)中进行迭代,并在对当前
好像没有,因为我有实现From for 的代码, 我可以转换 A到 B与 .into() , 但同样的事情不适用于 Vec .into()一个Vec . 要么我搞砸了阻止实现派生的事情,要么这不应该发
在 C# 中,如果 A 实现 IX 并且 B 继承自 A ,是否必然遵循 B 实现 IX?如果是,是因为 LSP 吗?之间有什么区别吗: 1. Interface IX; Class A : IX;
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我正在阅读标准haskell库的(^)的实现代码: (^) :: (Num a, Integral b) => a -> b -> a x0 ^ y0 | y0 a -> b ->a expo x0
我将把国际象棋游戏表示为 C++ 结构。我认为,最好的选择是树结构(因为在每个深度我们都有几个可能的移动)。 这是一个好的方法吗? struct TreeElement{ SomeMoveType
我正在为用户名数据库实现字符串匹配算法。我的方法采用现有的用户名数据库和用户想要的新用户名,然后检查用户名是否已被占用。如果采用该方法,则该方法应该返回带有数据库中未采用的数字的用户名。 例子: “贾
我正在尝试实现 Breadth-first search algorithm , 为了找到两个顶点之间的最短距离。我开发了一个 Queue 对象来保存和检索对象,并且我有一个二维数组来保存两个给定顶点
我目前正在 ika 中开发我的 Python 游戏,它使用 python 2.5 我决定为 AI 使用 A* 寻路。然而,我发现它对我的需要来说太慢了(3-4 个敌人可能会落后于游戏,但我想供应 4-
我正在寻找 Kademlia 的开源实现C/C++ 中的分布式哈希表。它必须是轻量级和跨平台的(win/linux/mac)。 它必须能够将信息发布到 DHT 并检索它。 最佳答案 OpenDHT是
我在一本书中读到这一行:-“当我们要求 C++ 实现运行程序时,它会通过调用此函数来实现。” 而且我想知道“C++ 实现”是什么意思或具体是什么。帮忙!? 最佳答案 “C++ 实现”是指编译器加上链接
我正在尝试使用分支定界的 C++ 实现这个背包问题。此网站上有一个 Java 版本:Implementing branch and bound for knapsack 我试图让我的 C++ 版本打印
在很多情况下,我需要在 C# 中访问合适的哈希算法,从重写 GetHashCode 到对数据执行快速比较/查找。 我发现 FNV 哈希是一种非常简单/好/快速的哈希算法。但是,我从未见过 C# 实现的
目录 LRU缓存替换策略 核心思想 不适用场景 算法基本实现 算法优化
1. 绪论 在前面文章中提到 空间直角坐标系相互转换 ,测绘坐标转换时,一般涉及到的情况是:两个直角坐标系的小角度转换。这个就是我们经常在测绘数据处理中,WGS-84坐标系、54北京坐标系
在软件开发过程中,有时候我们需要定时地检查数据库中的数据,并在发现新增数据时触发一个动作。为了实现这个需求,我们在 .Net 7 下进行一次简单的演示. PeriodicTimer .
二分查找 二分查找算法,说白了就是在有序的数组里面给予一个存在数组里面的值key,然后将其先和数组中间的比较,如果key大于中间值,进行下一次mid后面的比较,直到找到相等的,就可以得到它的位置。
我是一名优秀的程序员,十分优秀!