2
\$\begingroup\$

I think that everyone is familiar with the concept of a context (such as HttpContext in ASP.NET) where you can put some shared resources and take them back later in another module (I think the most used scenario is current/logged in user information).

Well it's obvious that usually these contexts are generic (and in a strong typed languages such as C# you should access their members using keys) and thus we have to write codes like this al the time :

var user=(User)HttpContext.Current.Items["CurrentUser"];

This code has some problems in my opinion:

  1. Use of magic keys (we should always use constants instead of in-line strings)
  2. Possible null reference exception (either by misspelling the key or a missing key)
  3. Value always should cast to original value

In other words a developer should know a lot of things in order to write this line of code.

There's no doubt that we should re-factor our code so we can prevent upcoming problems.

One solution might be having a static member of a common class that every other module can call such as:

public class UserController
{
       public static User GetCurrentUser()
       {
             return (User)HttpContext.Current.Items["CurrentUser"];
       }
}

Actually we just move our repeated code to one single place as you can see therefore we can control all aspects of it (exception management and casting) in one place and now our fellow developers can write codes like this:

var user=UserController.GetCurrentUser();

Nice and easy, but is there any way to pretend that GetCurrentUser was a member of current module?

To do that we can have all our modules to be inherited from the same base class but I don't think that is a good idea because inheritance always makes a solution more complex specially in languages like C# with no multiple inheritance.

Then I thought: what if we could have an extension method that we could use in our modules? Something like this:

public static User GetCurrentUser(this IUserInfoConsumer self)
{
       return (User)HttpContext.Current.Items["CurrentUser"];
}

As you can see IUserInfoConsumer is a marker interface to mark our modules/components as a consumer of user information (it has no members) so that in every class that has this maker interface we can write a code like this:

var user=this.GetCurrentUser();

I would like to know what you think about this approach. Any other ideas?

\$\endgroup\$

closed as off-topic by BCdotWEB, Ben Aaronson, Mast, Alex L, Malachi Jun 5 '15 at 14:43

This question appears to be off-topic. The users who voted to close gave this specific reason:

If this question can be reworded to fit the rules in the help center, please edit the question.

  • \$\begingroup\$ What you've got there is a fairly basic Service Locator pattern. Have you considered using a Dependency Injection framework instead? \$\endgroup\$ – Nick Udell Jun 5 '15 at 11:06
  • \$\begingroup\$ Unfortunately I am not a fan of IoC because I think it will add to a code base complexity but I really like to see your solution using an IoC container . It would be great if you could add it as an answer here :) \$\endgroup\$ – Beatles1692 Jun 5 '15 at 11:09
  • 4
    \$\begingroup\$ Isn't this question more relevant on programmers.stackexchange.com ? To me, this question falls into "if your question is not about a particular piece of code". \$\endgroup\$ – BCdotWEB Jun 5 '15 at 11:54
  • \$\begingroup\$ I think this would be an interesting question if migrated to programmers. \$\endgroup\$ – Ben Aaronson Jun 5 '15 at 12:17
0
\$\begingroup\$

When I encountered a similar issue I had a base controller that the rest of my controllers inherited from. Then, on that base controller there was a read only property named User that got the current user.

Personally I think inheritance can be confusing when it is abused just like everything else. As long as you keep your base controller relatively lean, and don't use it as a place to drop random methods which may not used in every controller, then I think inheriting from a base controller would be a pretty straight forward solution.

\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.