views:

1729

answers:

5

I've got a VB.NET module that reads from a resource file to display text in the correct language. Here's my problem - this code is shared between a web application and a non-web application, In the web application, I'm using System.Web.HttpContext to determine the user's preferred language, but now my Windows app won't even compile, because it says HttpContext isn't defined (I've already tried adding an imports for the full namespace - no dice).

I would love to use some kind of try/catch block if I can't otherwise work around it, but that doesn't change that the windows app won't compile with a reference to HttpContext in it. Without moving this chunk of code into a new file and including it only in the web application (I don't own that app, so I'd rather not deal with those implications), is there another choice I have to deal with this?

If it doesn't make sense, please let me know and I'll do my best to clarify.

SOLUTION: I just added a reference to System.Web, which allowed my application to compile. I also wrapped the HttpContext reference in an "If HttpContext.Current isnot Nothing Then...End If" block, which causes it to skip over the code if it's not running as a web application, which is exactly what I was looking for.

A: 

You can add System.Web.dll to your application and then use HttpContext. The problem is that there isn´t a HttpContext in you win application, so you should use a web service or WCF to communicate between the two applications.

vimpyboy
+1  A: 

Even if the app would compile you'd get the problem of no HttpContext in WinApp.

You could refactor the webapp so that instead of HttpContext it would use a service eg. IContextService or a bunch of services (ICacheService, ISessionService, etc.).

There would be two implementations of the service: one for the web app that would use HttpContext and one for the winapp which implementation would contain necessary logic to determine user preferences (language, etc.).

If the preferences are stored on the server you would need to implement some kind of service to communicate between your winapp and the server.

A: 

If possible, the probably best thing you could do is to completely remove the dependency on having a HTTP-context in the shared assembly.

For example, the method you mention which uses the HttpContext to get the user's preferred can be refactored so that the language is given as a parameter instead. When you call the method from your web application you can pass in the language from the HttpContext, and when you call it from the Windows application you will need to pass in the language from another source.

JacobE
+1  A: 

I think you could use a little bit of decoupling!

If you'd create a interface like this (in you BLL layer for instance)

public interface IPreferredLanguage
{
     String PeferredLanguage { get; set; }
}

and you'de create two implementations:

In you website project:

public class WebPeferredLanguage : IPreferredLanguage
{
     public String PeferredLanguage
     {
          get
          {
               return // retrieve the language from the http context
          }
          set
          {
               // set the preferred language in the HttpContext
          }
     } 
}

In your winforms project:

public class WinformsPeferredLanguage : IPreferredLanguage
{
     public String PeferredLanguage
     {
          get; set; // automatic properties
     } 
}

Hereafter you use Inversion of Control (Unity, StructureMap, MicroKernel) to configure in your webconfig that an instance of WebPeferredLanguage should be used and a singleton instance of WinformsPeferredLanguage should be returned in your winforms.

In your code whenever you need to know the language, you just ask the IoC container for the correct implementation of IPreferredLanguage, and it will return an object of the type which you have configured.

so in your bll you could program (for example):

public String GetEmailMessage()
{
    var currentLanguage = IoC.Resolve<IPreferredLanguage>().PeferredLanguage;
    return Resources[currentLanguage ].EmailMessage;
}

After writing this, I see that you wanted a VB.NET solution. Well, the examples still apply, only it's slightly different grammar (sorry if it's harder to read this way).

Davy Landman
ps, this is not the way to use a IoC container, you should use dependency injection to have the IPrefferedLanguage implementation injected.
Davy Landman
+2  A: 

Hello,

If you reference the System.Web assembly, you should then be given access to HttpContext.Current, which is a reference to the currently running web app's HttpContext object. If the application is a normal Win32 app, this reference should be a null pointer. Thus in C# you would use: if (HttpContext.Current == null) or in VB you could use: If HttpContext.Current Is Nothing Then

However, I have never tried doing something of this sort, so I can't guarantee the outcome. Let me know if that works for you.

Thanks, C

regex
Well it does not work if you are running NUnit GUI tool, it is not null in this case :(
Binoj Antony