【问题标题】:如何避免循环依赖但从父项目传递信息?
【发布时间】:2022-01-22 23:39:41
【问题描述】:

背景:我正在处理一个包含多个项目的大型解决方案。目标是将在项目 A 中检索到的简单用户输入(长度为 3 的两个整数数组和一个布尔值)传递给项目 B,在该项目 B 中,某些函数使用它。项目 B 是一个视图模型。但是,项目 A 引用了项目 B(例如,将项目 B 命名为引用),因此为避免循环依赖,我不能从 B 引用 A。

很明显,非常初学者,但这是在专业环境中,所以我只能“改造”这么多。我在 Visual Studio 中工作。

想法:我能想到的解决方案是,在项目 B 中,在编译时生成这些 int 和 bool 的一些内存。然后在运行时,将其填充到项目 A 中,然后由项目 B 检索此信息。

目前我所拥有的根本没有这样做,但我会发布我目前拥有的。在项目 B 中,我有一个合适的文件:

namespace NameSpaceB
{
  public struct Inputs
  {
    public int[] array1;
    public int[] array2;
    public bool t;
  }
}

现在前往项目 A,它会是这样的:

using NameSpaceB;

/* what follows is some structure already present in the solution, not my work */
namespace NameSpaceA 
{
  ... 
  internal public class MyClass
  {
    public static void MyFunction()
    {
      ...
      int[] inputs1 = { 1, 2, 3 }; /* assume these are inputs from a View model during run time */
      int[] inputs2 = { 4, 5, 6 };
      bool T = true;

      /* here is where I'd like something along these lines */
      Inputs inputInfo;
      inputInfo = default;

      Array.Copy(inputs1, Inputs.array1, 3);
      Array.Copy(inputs2, Inputs.array2, 3);
      Inputs.t = T;
      ...
    }
  }
}

现在理想情况下,我想在 MyFunction() 执行后检索项目 B 中的内容 inputInfo。我的 View 项目中将有默认输入(出现 UI),因此希望在我的数组中总能找到“那里”的东西。

我认为这样做的方法是在项目 B 中,在编译时为该结构分配内存,以便两个项目在运行时都可以访问它。我已经进行了一些谷歌搜索,但正在努力了解如何最好地做到这一点,或者即使我的想法是一个好主意。

【问题讨论】:

  • 把共享的东西放到C里,A和B都引用C?
  • 是的,这将是我的第一个建议。也就是说,我觉得这里有太多假设,无法让你的问题有意义地回答。请发布您的实际代码,而不是一些手动的虚构代码。您发布的内容看起来有几个问题。
  • @LasseV.Karlsen 啊,我确实想到了这个,但是创建第三个项目纯粹是为了托管这么少量的数据,感觉有点浪费。除非我误解了你?
  • 无论如何你都不能在编译时分配内存,在 C# 中不能以任何合理的方式分配内存。
  • 这个标题听起来像是一个 XY 问题。询问如何在编译时分配内存是一个次要问题,与解决您遇到的实际问题的具体方法有关,这可能是(尽管有点不清楚)您在两个项目共享的类型声明中存在循环依赖关系。可能应该更改标题以代表实际问题。

标签: c# struct memory-management


【解决方案1】:

我认为你让这件事变得比它需要的复杂得多。如果项目 A 想给项目 B 中的某个方法提供一些数据,它会简单地调用该方法。如果所述方法采用某种类型的参数,则需要在项目 B 或 A 和 B 引用的其他项目中声明该类型。

即你的例子是这样的

public static void MyMethodInProjectA(){
    Inputs parameter = GetInputsFromSomewhere();
    MyProjectBClass.MyMethod( parameter );
}

此示例假定使用静态方法。如果你想调用一个实例方法,你显然需要引用该对象。

在某些情况下,生成数据的成本可能很高,因此您只想在需要时创建它。在这种情况下,您可以使用间接方式,例如使用委托:

public class MyProjectBClass{
    public Func<Inputs> InputSource {get;}
    public MyProjectBClass(Func<Inputs> inputSource) => InputSource  = inputSource;
    private void MyMethod()
    {
        Inputs i = InputSource();
        // use the inputs
    }
}
public class MyProjectAClass{
    MyProjectBClass bClass;
    public MyProjectAClass(){
        bClass =  new MyProjectBClass(GetInputsFromSomewhere);
    }
    private Inputs GetInputsFromSomewhere(){
        // Create a input object and return it.    
    } 
}

这样 MyProjectBClass 不需要关心生成输入的是什么,它只需要依赖一个标准的委托类型。

有时有用的另一件事是接口或基类。项目 B 可以创建一个在项目 A 中实现的接口。这允许项目 B 中的类使用项目 A 中的类的对象,但只能使用接口中暴露的部分。

【讨论】:

  • 感谢您的回答。我想我有很多东西要学!所以一个问题,项目B如何调用项目A中的方法,而不在我的项目B文件中写“使用NameSpaceA”?基本上,设置是这样的:一个有两个“页面”的应用程序(不确定正确的术语是什么;两个单独的 xamls)。输入被送入其中一个,由 A 控制,另一个有一个“播放”按钮,由 B 控制。这个想法是当点击“播放”时可以访问页面 A 上的输入。所以在一个理想的世界里,我希望 B 能够做 NameSpaceA.GetInputs(),但那是不可能的......
  • @luaa 查看使用委托的示例。当项目 A 中的类从项目 B 中的类创建对象时,它可以给它一个委托(即Func&lt;T&gt;),项目 B 中的类可以在需要时调用该委托。这样,项目 B 中的类就不需要依赖项目 A 中的任何内容,只需要依赖委托类型及其参数。
猜你喜欢
  • 1970-01-01
  • 2013-02-06
  • 1970-01-01
  • 2012-02-15
  • 2013-04-02
  • 1970-01-01
  • 2012-08-10
  • 1970-01-01
  • 2016-08-09
相关资源
最近更新 更多