在程序中的类之间共享值的技术

发布于 2024-08-25 16:31:22 字数 750 浏览 2 评论 0原文

我正在使用

Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + "\MyProgram"

As 来存储我的程序使用的多个文件的路径。我想避免在我的应用程序中粘贴相同的代码片段。

我需要确保:

  • 一旦设置了路径,就不会意外更改
  • 需要它的类可以访问它。

我考虑过:

  • 使其成为单例
  • 使用构造函数依赖注入
  • 使用属性依赖注入
  • 使用 AOP 在需要的地方创建路径。

每个都有优点和缺点。

单身人士是每个人最喜欢的替罪羊。我并不反对使用它,但如果可能的话,有充分的理由避免它。

我已经通过温莎城堡大量使用构造函数注入。但这是一个路径字符串,Windsor 不能非常优雅地处理系统类型依赖性。我总是可以将它包装在一个类中,但这对于像传递字符串值这样简单的事情来说似乎有点矫枉过正。无论如何,此路由都会向使用它的每个类添加另一个构造函数参数。

在这种情况下,我看到的属性注入的问题是,从设置值的位置到需要它的位置存在大量间接。我需要很长的中间人队伍才能到达所有使用它的地方。

AOP 看起来很有前途,无论如何我都计划使用 AOP 进行日志记录,所以这至少听起来是一个简单的解决方案。

还有其他我没有考虑过的选择吗?我对我所考虑的选项的评估是否有偏差?

I'm using

Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + "\MyProgram"

As the path to store several files used by my program. I'd like to avoid pasting the same snippet of code all over the my applcation.

I need to ensure that:

  • The path cannot be accidentally changed once its been set
  • The classes that need it have access to it.

I've considered:

  • Making it a singleton
  • Using constructor dependency injection
  • Using property dependency injection
  • Using AOP to create the path where its needed.

Each has pros and cons.

The singleton is everyone's favorite whipping boy. I'm not opposed to using one but there are valid reasons to avoid it if possible.

I'm already heavily using constructor injection through Castle Windsor. But this is a path string and Windsor doesn't handle system type dependencies very gracefully. I could always wrap it in a class but that seems like overkill for something as simple as a passing around a string value. In any case this route would add yet another constructor argument to each class where it is used.

The problem I see with property injection in this case is that there is a large amount of indirection from the where the value is set to where it is needed. I would need a very long line of middlemen to reach all the places where its used.

AOP looks promising and I'm planning on using AOP for logging anyway so this at least sounds like a simple solution.

Is there any other options I haven't considered? Am I off base with my evaluation of the options I have considered?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

飞烟轻若梦 2024-09-01 16:31:22

当有足够强烈的需求时,我从未见过为我自己的项目创建像 Environment 这样的静态类的问题。

MyAppEnvironment.ApplicationFolder

如果您使用注入传递值,那么您要么 a) 创建一个类来保存该值,要么 b) 传入一个字符串。后者是不好的,因为你的价值应该是恒定的。前者是有效的,但似乎是一个公平的开销,因为只有一个有效值(如果确实需要,您仍然可以模拟/伪造该值进行测试)。

我想你可以注入你的环境类,但对我来说这似乎有点矫枉过正。

I've never seen a problem with creating a static class like Environment for my own projects, when there's been strong enough need.

MyAppEnvironment.ApplicationFolder

If you're passing the value in using injection then you're either a) creating a class just to hold the value or b) passing in a string. The latter is bad, because your value should be constant. The former is valid, but seems like a fair overhead since there's only ever a single valid value (and you can still mock/fake that value for tests if you really need to).

I suppose you could inject your environment class, but for me this seems like overkill.

紫﹏色ふ单纯 2024-09-01 16:31:22

看起来您所拥有的相当于应用程序中的全局设置。使用 AOP o 构造函数注入来传递这种依赖关系似乎有些矫枉过正,因为更简单的解决方案就可以解决问题。

我在这里的偏好是在静态类上使用静态属性。我会添加一个特定的写入例程来防止多组。例如 ...

public static class GlobalSettings {
  private static string s_path;
  public static string Path { get { return s_path; } }
  public static void UpdatePath(string path) {
    if ( s_path != null || path == null ) { throw ... }
    s_path = path;
  }
}

It seems like what you have amounts to a global setting within your application. Using AOP o constructor injection to pass around this dependency seems like quite a bit of overkill since a simpler solution would do the trick.

My preference here would be to use a static property on a static class. I would add a specific write routine that prevents multiple sets. For example ...

public static class GlobalSettings {
  private static string s_path;
  public static string Path { get { return s_path; } }
  public static void UpdatePath(string path) {
    if ( s_path != null || path == null ) { throw ... }
    s_path = path;
  }
}
野生奥特曼 2024-09-01 16:31:22

我们将在构造函数中注入一个 IMyAppConfig 类型的类,它只是所有此类内容的包装器。

We would constructor inject a class of type IMyAppConfig which is just a wrapper for all this kind of stuff.

羁客 2024-09-01 16:31:22

如果您有一个标准的 .net 应用程序,您应该已经有一个设置类。您可以创建一个新设置并将该值设置为默认值等。

if you have a standard .net application, you should already have a settings - class. you could create a new setting and set that value as default value or so.

忘东忘西忘不掉你 2024-09-01 16:31:22

我的过程是总是问这样的问题:什么样的事情可以改变?当这些事情发生变化时,什么会造成最少的痛苦?哪些部分可以在其他系统中重用,以及如何最大程度地减少重用的痛苦?基本上,如何才能尽可能地解耦这些东西呢?

考虑到这一点,答案实际上取决于您正在开发的系统的详细信息。

在任何使用此路径的过程中,我可能会将其作为参数传递下去。这将从启动路径使用的任何操作开始。每个方法都应该“做好一件事”,如果路径是那件事的一部分,那么它应该是一个参数。在启动操作的类中(以及在控制该类的生命周期的任何类中,等等),我可能会将路径作为构造函数的一部分。

这是我过去用过的方法,效果很好。例如,在一个应用程序中我采用了这种方法,后来发现需要允许用户更改路径设置。通过遵循这种架构(并避免单例),已经使用该路径的对象可以继续使用旧路径而不会出现错误,但从更改点开始可以正确使用新路径。它刚刚起作用了。

并且这些类可以迁移到新项目,而不依赖于这个特定的细节。

My process is to always ask questions like these: What kinds of things can change? What would create the least amount of pain when those things change? What pieces can be re-used in other systems, and how can the pain of the reuse be minimized? Basically, how can these things be decoupled as much as possible?

With that in mind, the answer is really based on the details of the system that you are working on.

In whatever process uses this path, I would likely pass it down as a parameter. This would start at whatever action initiates the use of the path. Each method should "do one thing well", and if the path is part of that thing, then it should be a parameter. In the class that initiates the action (and in whatever classes control the lifetime of that class, etc.), I would likely make the path part of the constructor.

This is the method that I have used in the past, and it has served me well. For example, in one application I took this approach, and then later discovered a need to allow the user to change the path setting. By following this architecture (and avoiding a singleton) the objects that had already used the path could continue to use the old one without an error, but the new path was used correctly from the point of the change. It just worked.

And the classes can be migrated to a new project without a dependency on this particular detail.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文