【问题标题】:How can achieve this class structure with the right visibility modifiers? [closed]如何使用正确的可见性修饰符来实现此类结构? [关闭]
【发布时间】:2021-04-03 18:26:52
【问题描述】:

我正在与几个人一起开展一个项目,并希望在代码中强制执行某种结构,而不必在某处编写代码,并且依赖于每个人来记住和应用这个概念。

我正在开发一个处理文件和数据的框架,我当前的结构是这样的(第一行是命名空间,第二行是类名)。

当前结构:

我的目的是让 FileManager 和 DataManager 只对 EngineWorker 可用,这样外界就不能直接使用它们,通过 EngineWorker 中的方法强制使用它们。我发现只有两种方法,删除 static 关键字并将 EngineWorker 中的实例设为私有,或者在所有情况下将所有类加入同一个程序集并将访问权限从 public 更改为 internal

我希望有另一种方法,可以让我保持类静态和程序集不变。也许是因为他们都有相同的“父”命名空间Product.FrameWork

【问题讨论】:

  • @AlexeiLevenkov 抱歉,我不确定我是否理解。我没有将代码作为图片发布,而只是一张图表,以帮助人们理解我要问的内容。我认为将其用于内联代码会更加混乱且难以解释。

标签: c# class structure access-modifiers


【解决方案1】:

我认为这是一个非常好的问题,我不久前来到across the same situation,但始终找不到完美的解决方案。

我能想到的一个解决方案是将EngineWorkerDataManagerFileManager 放在同一个项目中(我们称之为IO.Project)并制作最后两个类@ 987654325@ 以确保外部世界通过EngineWorker 访问它们:

IO.Project

public class EngineWorker
{
    private DataManager _dataManager;
    private FileManager _fileManager;

    /* 
     * The limitation of this approach is that the outside world does not know about
     * the internal classes, so you cannot use constructor injection:
     * 
     * public EngineWorker(DataManager dataManager, FileManager fileManager)
     * {
     *    _dataManager = dataManager;
     *    _filerManager = FileManager;
     * }
     */

     // you can pass the internal dependencies into the constructor
     public EngineWorker(DbContext dbContext, FileManagerDepencency fileManagerDependency)
     {
        _dataManager = new DataManager(dbContext);
        _fileManager = new FileManager(fileManagerDependency);
     }

     // or you can use a Factory to instantiate EngineWorker
}

internal class DataManager
{
    private _dbContext;

    internal DataManager(DbContext dbContext)
    {
        _dbContext = dbContext; 
    }

    internal void DoWork()
    {
        // do something
    }
}

internal class FileManager
{
    private _fileManagerDependency; // <-- if this class has any dependency?

    internal FileManager(FileManagerDependency fileManagerDependency)
    {
        _fileManagerDependency = fileManagerDependency; 
    }

    internal void DoWork()
    {
        // do something
    }
}

这种方法的局限性在于不能注入内部类,因为外界不知道它们...相反,您可以使用工厂/提供者来实例化EngineWorker...或者您可以通过构造函数的依赖项(例如DbContext)并让EngineWorker 构造函数实例化其内部成员。


另一种解决方案是创建所有三个类public(这样您就可以使用构造函数注入)。但是我们还是要防止外界直接使用DataManagerFileManager...为了实现这一点我们制作了他们的方法(上例中的DoWork()intenal

【讨论】:

  • 如果你检查来电者怎么办?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-05-19
  • 1970-01-01
  • 2013-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多