c# – 体系结构:依赖注入,松散耦合的程序集,实现隐藏

c# – 体系结构:依赖注入,松散耦合的程序集,实现隐藏,第1张

概述我一直致力于一个个人项目,除了为自己创造有用的东西之外,我还试图用它来继续寻找和学习建筑课程.一个这样的教训就像一辆科迪亚克熊在自行车道的中间出现,我一直在努力奋斗. 这个问题本质上是依赖注入,程序集解耦和实现隐藏(即使用内部类实现我的公共接口)的交叉问题的混合. 在我的工作中,我通常发现应用程序的各个层都有自己的接口,这些接口是公开公开的,但在内部实现.每个程序集的DI代码将内部类注册到公共接口 我一直致力于一个个人项目,除了为自己创造有用的东西之外,我还试图用它来继续寻找和学习建筑课程.一个这样的教训就像一辆科迪亚克熊在自行车道的中间出现,我一直在努力奋斗.

这个问题本质上是依赖注入,程序集解耦和实现隐藏(即使用内部类实现我的公共接口)的交叉问题的混合.

在我的工作中,我通常发现应用程序的各个层都有自己的接口,这些接口是公开公开的,但在内部实现.每个程序集的DI代码将内部类注册到公共接口.此技术可防止外部程序集新建实现类的实例.然而,我在阅读这些解决方案时一直在阅读的一些书籍反对这一点.与我之前的想法相冲突的主要事情与DI组合根有关,并且应该保留给定实现的接口.如果我将依赖注册移动到单个全局组合根(正如Mark Seemann建议的那样),那么我可以远离每个必须运行自己的依赖注册的程序集.但是,缺点是实现类必须是公共的(允许任何程序集实例化它们).至于解耦组件,Martin Fowler指示将接口放在使用接口的代码中,而不是实现它的接口.作为一个例子,这里是他提供的图表,相比之下,我将如何通常实现相同的解决方案(好吧,这些并不完全相同;请关注箭头并注意实施箭头何时交叉汇编边界而不是组成箭头).

马丁风格

我通常看到的

我立刻看到了Martin图中的优势,它允许将较低的程序集换成另一个程序集,因为它有一个类在其上面的层中实现接口.但是,我也看到了这个看似很大的缺点:如果你想从上层换出组件,你基本上会“窃取”下层正在实现的接口.

在考虑了一点之后,我决定在两个方向上完全解耦的最佳方法是在各自的程序集中使用指定层之间契约的接口.考虑这个更新的图表:

这个坚果吗?它是对的吗?对我来说,这似乎解决了界面隔离的问题.但是,它不能解决无法将实现类隐藏为内部的问题.有什么合理的可以在那里完成吗?我不应该担心这个吗?

我脑海中浮现的一个解决方案是让每个层实现两次代理层的接口;一次是公共课,一次是内部课.这样,公共类只能包装/装饰内部类,如下所示:

有些代码可能如下所示:

namespace MechanismProxy // Simulates Mechanism Proxy Assembly{    public interface IMechanism    {        voID DoStuff();    }}namespace MechanismImpl // Simulates Mechanism Assembly{    using MechanismProxy;    // This class would be registered to IMechanism in the DI container    public class Mechanism : IMechanism    {        private Readonly IMechanism _internalMechanism = new InternalMechanism();        public voID DoStuff()        {            _internalMechanism.DoStuff();        }    }    internal class InternalMechanism : IMechanism    {        public voID DoStuff()        {            // Do whatever        }    }}@H_419_38@  

…当然,我仍然需要解决有关构造函数注入的一些问题,并将注入公共类的依赖项传递给内部类.还有一个问题是外部组件可能会新建公共机制……我需要一种方法来确保只有DI容器可以做到这一点…我想如果我能弄明白,我甚至不需要内部版本.无论如何,如果有人能帮助我理解如何克服这些架构问题,那将是非常感激的.

解决方法

However,the downsIDe is that the implementation classes have to be public (allowing any assembly to instantiate them).

除非您正在构建一个可重用的库(它在NuGet上发布并被其他代码库使用而您无法控制),否则通常没有理由在内部创建类.特别是在编程到接口之后,应用程序中依赖于这些类的唯一位置是组合根.

另请注意,如果将抽象移动到不同的库,并且使消耗和实现程序集都依赖于该程序集,则这些程序集不必相互依赖.这意味着这些课程是公共的还是内部的并不重要.

然而,几乎不需要这种分离级别(将接口放置在它自己的组件中).最后,它是关于部署期间所需的粒度和应用程序的大小.

As for decoupling assemblIEs,Martin Fowler instructs to put interfaces in the project with the code that uses the interface,not the one that implements it.

这是Dependency Inversion Principle,其中指出:

In a direct application of dependency inversion,the abstracts are owned by the upper/policy layers

总结

以上是内存溢出为你收集整理的c# – 体系结构:依赖注入,松散耦合的程序集,实现隐藏全部内容,希望文章能够帮你解决c# – 体系结构:依赖注入,松散耦合的程序集,实现隐藏所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1220401.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)

保存