开发者

Techniques for sharing a value among classes in a program

开发者 https://www.devze.com 2022-12-23 00:57 出处:网络
I\'m using Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + \"\\MyProgram\"

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 w开发者_运维知识库here 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?


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.


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;
  }
}


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


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.


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号