gpt4 book ai didi

c# - 解决模块化架构中的前向引用

转载 作者:太空宇宙 更新时间:2023-11-03 15:29:47 26 4
gpt4 key购买 nike

在我的 (C#) 软件项目中,我有几个模块(由单独的 Visual Studio 项目表示)- 由于历史原因 - 具有很多循环依赖性(紧耦合)。

我目前正在尝试解决/删除循环引用。我已经添加了依赖项注入(inject)——但这当然不会解决/删除循环引用。

所以,我在考虑使用事件来解决“前向”依赖关系。他们不会直接调用转发依赖项,而是会在此事件上注册。

但是,其中一些依赖项需要在其他依赖项之前执行,例如这个(简单的)示例:

void DeleteCompany(int companyId)
{
// must run before other dependencies
ForwardDepend1.OnCompanyDeleted(companyId);

// can run in parallel
ForwardDepend2.OnCompanyDeleted(companyId);
ForwardDepend3.OnCompanyDeleted(companyId);

// must run as last command
this.OnCompanyDeleted(companyId);
}

ForwardDependX 的所有类都依赖于当前类;所以这些是我要解决的循环引用。

有没有现成的模式可以解决这种“复杂事件”机制?或者是否有其他更好的方法来解决这个问题?

我尝试用谷歌搜索这个问题,但找不到任何适合搜索的关键字。

最佳答案

我认为使用事件来改进紧耦合设计并不是最佳选择,因为它们往往会使依赖关系不那么明显。而且您确实需要明确所有依赖关系以解决循环引用问题。

我建议您应用 dependency inversion principleinterface segregation principle循序渐进。将新引入的接口(interface)通过构造函数传递给它们的客户端,并使用 DI 进行组合。

此外,依赖可视化工具在这些情况下确实有帮助。我用过 Resharper 和 NDepend对于过去的这些任务,两者都很好。

DIP 示例

下面是一个示例,展示了如何使用 DIP 解决循环依赖。因此,假设您有两个相互依赖的类:

class A 
{
private readonly B _b;

public A(B b) {
_b = b;
}

public void DoIt() {
// ...
}
}

class B
{
public void DoSomething(A a) {
a.DoIt();
}
}

这意味着我们有一个像这样的依赖图:

A <--> B

现在在构成较弱依赖的类上引入一个接口(interface),在本例中是A(因为A只是在B中临时使用).

interface IA 
{
void DoIt();
}

class A : IA
{
private readonly B _b;

public A(B b) {
_b = b;
}

public void DoIt() {
// ...
}
}

class B
{
public void DoSomething(IA a) {
a.DoIt();
}
}

随着接口(interface)的引入,依赖圈被打破了:

 A ----
| |
v v
IA <-- B

关于c# - 解决模块化架构中的前向引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34151810/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com