How does C # library code know that it uses an application type without System.Web.dll?

We are developing several applications in Visual Studio 2010 using C # and .NET 4.0 on Windows. Two SilverLight applications using services from several WCF projects. Another is a console application.

We want to put some "common" functions in a separate library project in order to decompose and reuse the code. This library should know if the application is hosted (IIS, ASP.NET ...) as WCF services, or it works as a console application due to different file path processing.

In this regard, people point to the use of System.Web.dll to find out if the code is hosted using HttpContext, HostingEnvironment.IsHosted ... The problem is that this approach requires the inclusion of a link to the System. Web int he Library, which is unacceptable if this library refers to a console project with a client profile.

The idea is to use another method that does not require the use of the System.Web assembly.

+8
c # iis
source share
6 answers

If you only need to get the file path in the folder containing the application (as in the question about the question), you can use:

Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "filename") 

For an ASP.NET application, this will be the root folder (the same as MapPath ("~ /" + filename)), for a console application, it will be the folder containing the executable.

From the comment on the original question:

when running as a console application, just use the file name as the relative path

I would not recommend using a relative path. This will apply to the current working directory, which may differ from the application directory.

+8
source share

There are several ways to check if an ASP.NET application is or not.

Check the configuration file name

 if ("web.config".Equals(Path.GetFileName(AppDomain.CurrentDomain.SetupInformation.ConfigurationFile), StringComparison.OrdinalIgnoreCase)) { // ASP.NET application } 

ASP.NET application does not have write assembly

 if (Assembly.GetEntryAssembly() == null) { // ASP.NET application } 

ASP.NET application uses shadow copies of all DLL files. However, I'm not sure if this is possible in other types of applications.

 if (AppDomain.CurrentDomain.ShadowCopyFiles) { // ASP.NET application (probably) } 
+8
source share

Another reflection idea: use System.Web, but through reflection:

  • use AppDomain.CurrentDomain.GetAssemblies() to find out if System.Web is loaded; if not, you are not posted
  • if it is loaded, use reflection to invoke HostingEnvironment.IsHosted

It turned out that this is easier said than done, but it seems like a trick:

 public static bool IsHosted() { try { var webAssemblies = AppDomain.CurrentDomain.GetAssemblies() .Where(a => a.FullName.StartsWith("System.Web")); foreach(var webAssembly in webAssemblies) { var hostingEnvironmentType = webAssembly.GetType("System.Web.Hosting.HostingEnvironment"); if (hostingEnvironmentType != null) { var isHostedProperty = hostingEnvironmentType.GetProperty("IsHosted", BindingFlags.GetProperty | BindingFlags.Static | BindingFlags.Public); if (isHostedProperty != null) { object result = isHostedProperty.GetValue(null, null); if (result is bool) { return (bool) result; } } } } } catch (Exception) { // Failed to find or execute HostingEnvironment.IsHosted; assume false } return false; } 

Reflection is probably expensive, so do it once and cache the result. I'm also not sure what the best way to find a specific assembly and type is, but this method works.

+4
source share

you can do this through Reflection using the GetCallingAssembly method. For example

 public string GetPath() { if(Assembly.GetCallingAssembly().FullName == "WebProjectDLLName") { //From web project } else { // other than web project } } 

Although this is not a general solution, you can improve it using the GetReferenceAssemblies method (when invoking the assembly).

+1
source share

Since Silverlight and console applications will know about their environment, you can put the appropriate information in your App.config files so that the shared library can access the environmental information through the configuration, rather than trying to execute it yourself.

0
source share

Probably the easiest way is to create an enumeration in the library of the various types of applications for which the library will be used. Create a variable in the enumerated library. Then the application using the library will set the variable with this enumeration, and then the library will find out what type of application is using it.

Like this:

 public static enum applicationType { hosted, console}; public static applicationType applicationConsumerType = applicationType.console; 

You can also specify an enum typeType type parameter needed as part of the library method calls, and thereby get the application type. Then no matter what you always know, since this is the required parameter.

0
source share

All Articles