views:

310

answers:

6

I have a dll which is based on .net 3.5 -- it uses internally for example Linq, but the exposed API is straightforward, no fancy stuff. Since C# generics are resolved at compile time I assume that for calling party all it counts is API (all public parts).

However when I try to use this dll from net2.0 project I get info, that the dll cannot be referenced because the dll or one of its dependencies requires a later version of .net framework.

I can install any .net version I want on target computer (when entire app is installed), but I cannot change .net version for the project itself.

So: how to solve this? When adding a C dll to this project I had no such problems, so are C# dlls self-contained or not?

+5  A: 

C# dlls need to have the .Net runtime to run as they are not compiled down to machine code. In this case the dll says it requires Net 3.5 so all your project will have to use 3.5 or higher.

To keep your project as Net 2.0 you would need to build another executable to contain the 3.5 DLL and communicate across separate processes.

The C DLL worked as it is compiled down to native code and does not require the .Net framework. (or at least not version higher than 2.0)

Mark
+1, good answer. Also, I think you meant 3.5 DLL (not 3.2)
Pretzel
As I said, I can install 3.5, no problem, but I cannot set 3.5 for the project, because someone could use some 3.5 features by accident.
macias
Yes I have fixed that now - thank @Pretzel
Mark
@macias - if the project is using version X then all DLLS in it MUST be version X or less. So you can't
Mark
In fact you give the reason "because someone could use some 3.5 features" and the same reason holds for you
Mark
While I get "you can't" answer, I still don't understand it. Project is like a sandbox with reference to dll which is another sandbox. So I still don't see why the limits of the dll cannot be wider than the project. It applies to all software, not only C#.
macias
The issue is that pats of your code and the Linq DLL have links to different versions of the .Net framework - Linq probably requires features that are not in the framework you use and you can really only use one framework at once and this has to be one that provides all resources ie the higher version (Though as per @Craig's answer it is not exactly that simple and can use the same runtime but as you want Linq you can't write the code.))The issue is the framework and its dependencies not the code directly - ie the sandboxes are different
Mark
That's bad. This kills the idea of separating code (for example plugins) because it means that even if the API of library is OK, its (binary) requirements has impact on main application **source**. I come from C++/Linux world and using different versions of libraries (directly and non-directly) is 100% legit.
macias
the point is .Net (and java) have a runtime which defines the API - not code like C++ - also in C++ try using a gcc 2.95 plugin with a gcc 4.4 app. (Only C APIs give full independence)
Mark
Mark, thank you very much for that comment!
macias
+2  A: 

If you are using linq to objects, then you can use Linq Bridge: http://www.albahari.com/nutshell/linqbridge.aspx

this is a Linq to objects implementation for .net 2.0.

You will still have to compile using vs2008 but you can compile with .net 2.0 as a target platform in that case. (This is because the C# 3 compiler understands linq clauses even if you target .net 2.0, it will simply resolve the calls to linqbridge instead of the .NET 3.5 libraries in this case)

Roger Alsing
+1  A: 

C# DLLs are not self-contained. If your 3.5 DLL needs LINQ, it depends on system assemblies from the 3.5 (3.0 to be exact) framework, therefore the entire application depends on this version.

You could load the 3.5 assembly dynamically and use reflection to get access to the functions you need. This requires some overhead, of course.

MartinStettner
+3  A: 

I've been using System.Core and the new System.Web.Extensions (for example) from 3.5 in an ASP.NET 2.0 app (using VS2005) for a while now with no problems. Similar to what Scott Hanselman blogged about here. So yes, it's possible.

.NET 3.5 still runs on the same CLR as .NET 2.0. So at runtime it's all the same. (Assuming you've tracked down any dependencies and copied those 3.5 DLLs to your bin folder as well.)

The only real limitation is what C# language features you can use at development time. Such as 'var', extension methods, or LINQ query syntax.

Craig
+2  A: 

If you're using .NET 3.5 libraries then your application's requirements should be such that any consumer of it's API's should also be using .NET 3.5.

The only way you can bypass this is if you package all the dependencies of your application along with it. This means libraries your application uses which depend on the .NET 3.0 and 3.5 frameworks.

However, I'm not sure of the legality of ripping out chunks of the .NET frameworks and packaging them with an app. I'd read the EULA before doing anything like this. IMO, it's not worth the hassle; just install 3.5, ask your users to install 3.5 and be done with it or use only 2.0 features and libraries. At the very least, hacking around like this will only cause you more pain with deployment if there are framework updates in the future.

In either case, your app will work on .NET 2.0 as 3.0 and 3.5 are just extra libraries on top of the 2.0 runtime and libraries (as Craig mentioned) as long as all your dependencies are there.

alimbada
I was thinking exactly about such thing, only that I don't rip anything, but I am telling what the requirement is for the library. Till now I am still surprised that C# library is not treated like a black box, but its internals "leak". This means also that C# is not suitable for plugins, because even if the API is compliant, with newer .net used in the library this would mean rebuilding whole application.
macias
I think you have .NET and C# confused. The language is not the same as the runtime. Also, there is no **need** to rebuild a library for a new .NET version. You only need to rebuild **if** you are using features of the new version.
alimbada
A: 

Nothing pretty but there are ways to get the code happily working together (in the order of preference):

1) Upgrade both projects to 3.5

If I understand you correctly then your .net FW 2.0 Program will have dependency on 3.5 Library, which means for every functionality of the Program to work, it now requires FW 3.5. Since you state to have the code and authority to recompile the the Program AND install whatever FW on deployment, then you can upgrade it to 3.5. Sounds simple, but since you did not do this, then I guess you have good reasons (like other programs being higher up the call chain which you cannot upgrade to 3.5/recompile.)

2) Go around the FW2.0 compiler

Build the Program when referencing the 2.0 version of Library (or dummy, just providing the public API). Build the 3.5 version of Library separately without Program (hence removing the need to reference the wrong FW assembly) and deploy the 3.5 version instead of the 2.0 version. Since 2.0 and 3.5 use the same CLR runtime then fooling the compiler is enough. As long as the deployment maching has FW 3.5 installed, everything should be fine. Note: everything is fine even if you have just .net 2.0 present on deployment machine and the user does not call .net 3.5 classes. If he does, there will be crash ;)

3) downgrade Library to 2.0

if you use only some classes of the .net FW then you could remain using the 2.0 compiler by adding those missing future assemblies to project. (this is the solution from Hanselman link shared by Craig). As already noted, you'll lose 3.5 compiler's syntactic sugar like vars.

Choose whichever suits your situation best.

ImreP