views:

144

answers:

3

I have a static class that contains my database logic.

This class is used in a website, web services and as part of a middleware component.

For every method in this class I need a piece of context information from the caller. In the case of the web site this would be user information, for the web service and middleware component, this would identify the calling service.

I can't store this value in the config because this might differ per user and I don't always have a httpcontext to get this from.

I could easily add a new parameter onto every method in this class or I could change it from a static class so that it has a single non-static property but neither of those solutions seem very elegant.

So are there any other options I haven't considered?

+1  A: 

I would add the parameters. It doesn't seem inelegant to me - you need context info, and the only way to get it in a static class is by passing it in.

Ray
the problem with this is that is does not seem very DRY to me.
Chris Simpson
I don't see this as violating DRY, necessarily. Whether you keep the static class, or switch to creating instances, those methods will need the context info. They will get it from a parameter or from an instance member - neither seems to me like a problem. For a class which is part of your db middleware, and not part of your context, I think a static class is more appropriate. Also, if your static class is very large, and your context data is very small, I would keep the static class.
Ray
every method makes use of a private method to set up the connection. It is here I'm using the context info so each method does not "directly" use the context if you appreciate the subtle difference? Having this parameter on every method and then passing it through to the private method does sound like repetition to me.
Chris Simpson
I see what you mean, but instead of passing context with every method call, you are now passing context with every instantiation. It's probably less typing, but it is more garbage collection. And I don't see it as more DRY. That said, without seeing your code, I really have no idea what I am talking about. And it is, for the most part, a philosophical fine point anyway. Cheers :)
Ray
+6  A: 

If all the methods need some state, it sounds a lot like you should create an instance and pass that state via the constructor.

Changing the design from a bunch of static methods to an instance will also make it easier to test the class.

Brian Rasmussen
The more I think about it, the more I'm coming around to this idea. The only downside is the extra line of code required every time a method call is required.
Chris Simpson
+1 - this is a classic case for dependency injection/IoC (manual or via a container framework). See also http://www.amazon.com/Working-Effectively-Legacy-Michael-Feathers/dp/0131177052
TrueWill
Do you create the instance for each call? Otherwise I don't see how you would need extra code using an instance.
Brian Rasmussen
@Brian - fair point, it's not every method but for the purpose of the website it will be once per controller action which is not much more than 1 call at a time.
Chris Simpson
A: 

The only other option is a Dependency Injection scheme:

  • All static class methods refer to a static Context fetcher
  • The fetcher calls a component that knows how to fetch the Context for a particular environment
  • Each environment injects its Context-aware component to be used by the fetcher

I prefer explicit versus implicit so I'd favor passing the Context as a parameter, but if you're a stickler for clean method signatures this would work.

Corbin March