Detecting If A Namespace Is Available

  • Thread starter Thread starter Justin R.
  • Start date Start date
J

Justin R.

Is it possible to structure a program in a way that it could, for
instance, utilize LINQ if .NET 3.5 is installed, but not if the client
only has .NET 2.0?

Another example, I have the Parallel Extensions CTP installed on my
PC, but there's no way of predicting if my client will have it
installed. If they do have it installed, I want my program to take
advantage of its capabilities. However, I do not want to make it a
requirement for my program to run, so if the client doesn't have it
installed I want my application to remain fully functional.
 
Is it possible to structure a program in a way that it could, for
instance, utilize LINQ if .NET 3.5 is installed, but not if the client
only has .NET 2.0?

Another example, I have the Parallel Extensions CTP installed on my
PC, but there's no way of predicting if my client will have it
installed. If they do have it installed, I want my program to take
advantage of its capabilities. However, I do not want to make it a
requirement for my program to run, so if the client doesn't have it
installed I want my application to remain fully functional.

Detection of things like this is possible, but not always easy to do
from your end. That said, there are several ways to do it, none of
them really specific to C# and .NET.

The first method would be to divide your application into logical
subsystems and isolate the use of features that can be optionally used
by your program. For example, write a module that can do things using
LINQ or without LINQ if it's not available; then you can load the LINQ
module at run-time, and if it throws an exception while detecting
whether or not LINQ is available, you can fall-back to the non-LINQ way
of doing it. By extension you could do this for PE CTP, or even for
the presence of Windows and WinForms (say, if you wanted to be portable
to Linux, you could easily do that by isolating all Win32 P/Invokes and
WinForms into its own modules, and then construct other modules that
have Linux-specific P/Invokes and GtkSharp).

This can easily become a lot of work, though, if you have more than a
small number of optional features that you want to support the presence
or absence of on the target machine, because you may have to write a
lot of similar (and duplicated) code that works both with and without
each feature.

You could make your application less flexible by using preprocessor
definitions, and build your application both with and without them
defined. Say, define WITH_LINQ to build a LINQ-enabled version of the
application, and WITH_PE_CTP to build with support for Parallel
Extensions. This places the code in the same file, then, which may or
may not be what you want. At least that way, you could use partial
classes and conditionally compile only one of the implementations
depending on what build-time preprocessor defines are enabled.

One other alternative, depending on how hard your dependencies are, may
be to just require the feature from your user. For certain things that
makes sense: most .NET programmers don't even think about the fact that
they could support users running on Linux and instead make their
application have a hard dependency on Windows and the Win32 and
WinForms APIs. If the Win32/WinForms code is scattered all throughout
the application, then this is the only alternative short of some major
refactoring to isolate the code into its own subsystem.

The one thing that you gain using C# and .NET is that you _can_ detect
these things at runtime: Your code can potentially run on several
operating systems (Windows, FreeBSD, Linux) with several types of GUI
(WinForms, GtkSharp) without requiring recompilation if you code with
these ideas in mind ahead of time.

--- Mike
 
Detection of things like this is possible, but not always easy to do
from your end.  That said, there are several ways to do it, none of
them really specific to C# and .NET.

The first method would be to divide your application into logical
subsystems and isolate the use of features that can be optionally used
by your program.  For example, write a module that can do things using
LINQ or without LINQ if it's not available; then you can load the LINQ
module at run-time, and if it throws an exception while detecting
whether or not LINQ is available, you can fall-back to the non-LINQ way
of doing it.  By extension you could do this for PE CTP, or even for
the presence of Windows and WinForms (say, if you wanted to be portable
to Linux, you could easily do that by isolating all Win32 P/Invokes and
WinForms into its own modules, and then construct other modules that
have Linux-specific P/Invokes and GtkSharp).

This can easily become a lot of work, though, if you have more than a
small number of optional features that you want to support the presence
or absence of on the target machine, because you may have to write a
lot of similar (and duplicated) code that works both with and without
each feature.

You could make your application less flexible by using preprocessor
definitions, and build your application both with and without them
defined.  Say, define WITH_LINQ to build a LINQ-enabled version of the
application, and WITH_PE_CTP to build with support for Parallel
Extensions.  This places the code in the same file, then, which may or
may not be what you want.  At least that way, you could use partial
classes and conditionally compile only one of the implementations
depending on what build-time preprocessor defines are enabled.

One other alternative, depending on how hard your dependencies are, may
be to just require the feature from your user.  For certain things that
makes sense: most .NET programmers don't even think about the fact that
they could support users running on Linux and instead make their
application have a hard dependency on Windows and the Win32 and
WinForms APIs.  If the Win32/WinForms code is scattered all throughout
the application, then this is the only alternative short of some major
refactoring to isolate the code into its own subsystem.

The one thing that you gain using C# and .NET is that you _can_ detect
these things at runtime:  Your code can potentially run on several
operating systems (Windows, FreeBSD, Linux) with several types of GUI
(WinForms, GtkSharp) without requiring recompilation if you code with
these ideas in mind ahead of time.

        --- Mike

How would I detect an exception thrown when LINQ is not available?
 
How would I detect an exception thrown when LINQ is not available?

Compile the module using a compiler that has the libraries, and enclose
the detection code (located in the module I mentioned earlier) inside
of a try...catch block. If an exception is thrown you'll catch it in
the catch block and you can load your alternate module.

--- Mike
 
Compile the module using a compiler that has the libraries, and
enclose the detection code (located in the module I mentioned
earlier) inside of a try...catch block. If an exception is thrown
you'll catch it in the catch block and you can load your alternate
module.

That said, it actually may even be easier than that. You'll have to
experiment, but the CLR probably will even refuse to load the library
if it's dependent on LINQ and it can't resolve those dependencies.
Then you could just catch that exception instead.

See:

http://msdn.microsoft.com/en-us/library/25y1ya39.aspx

--- Mike
 
Michael said:
That said, it actually may even be easier than that. You'll have to
experiment, but the CLR probably will even refuse to load the library
if it's dependent on LINQ and it can't resolve those dependencies.
Then you could just catch that exception instead.

See:

http://msdn.microsoft.com/en-us/library/25y1ya39.aspx

I think it is the only way. If not using reflection there
will be dependency problems loading the calling code.

Arne
 
Back
Top