Refer .NET assembly based on compiler switch - c#

I need to add reference to another assembly in my c# project based on some compiler switch like #ifdirective. For example I want to add reference to logger DLL in my project only when I need it. Is this possible?

As far as I know, a referenced assembly that isn't used AT ALL, isn't a problem. You can even keep it as reference.
As long as your code doesn't trigger the assembly to be loaded, there is no need to have that file available.
I would suggest though to check whether you really need this, and if you can workaround this by creating interfaces and dynamically load the assembly (using Assembly.LoadFrom).

Related

WPF Only Require Assembly References When Dependent Functions Used

I have a created a WPF assembly that offers a set of attached behaviors (attached properties with property changed code) that can affect a wide range of third party controls.
Example:
TreeViewBehavior: Requires reference to Windows.Controls
RadTreeViewBehavior: Requires reference to
Telerik.Windows.Controls.Navigation
Some of my users will never use the RadTreeViewBehavior, but they still have to have a reference to Telerik.Windows.Controls.Navigation in their project.
How can I made it so that my users will only need to add references to assemblies that they are actually using?
I hope this makes sense.
You can't, your assembly is dependent on Telerik.Windows.Controls.Navigation and without it your assembly is incomplete. You will either need to remove any use of that assembly in yours, or try merging/embedding the assemblies using something like IlMerge or SmartAssembly.
I would recommend splitting the assembly into one that has behaviours for System.Windows.Controls and one that has behaviours for Telerik.Windows.Controls.Navigation

Adding references for code moved into a class library

From a solution, which I made in Visual Studio 2013, I want to transfer a method to a DLL (class library project).
When I paste the method in the DLL project, it doesn't recognize parts of the code and it's showing this error`:
"are you missing a using directive or an assembly reference?"
Because of that, the DLL can't be built. I am assuming, that a certain reference to the solution is required, but I am not sure how to proceed.
I know how to add a reference from a solution to a DLL, but I'm not sure how it's done the other way around or even if it's possible.
You can't add reference to EXE from class library (assuming EXE uses that class library) as it will introduce circular reference.
Usually you need to refactor all dependencies so class library either have them all or allow application to inject dependencies from EXE/other clients. In later case class library needs to define base classes/interfaces to allow such injection.
Yes, you need to restore the same references that the original project uses, if they are used in the code you want to move.
If you need to do this by hand (i.e. without tools like ReSharper):
Move the code to the new assembly.
For each namespace or type giving the error, find it in the Object Browser.
Locate the assembly containing that namespace and type, and add a reference to that assembly in your new project.
You may also have to add a Project Reference to the original project.

Loading an assembly / module into a dynamic assembly

I have one assembly that's created already, say Static.dll, and a dynamic assembly I'm creating at runtime, say Dynamic. Dynamic creates some IL code to create a new type from Static.dll. When Dynamic is created (it saves successfully), the executable, when ran, errors out because it's unable to load the assembly Static.dll type. I believe this is happening since the Dynamic exe output can't find this dll (or at least this is my guess).
How can accomplish adding in this Static.dll reference so that when someone runs the resulting executable output of Dynamic that it can find the referenced types?
I know about Assembly.Load(), but this alone doesn't change anything. Or at least, I'm not sure what this gives me since I don't need to use the type at runtime, but rather when running the Dynamic executable.
Lastly, I control the Static.dll, so if there is something I can do with the project to fix it, It could be done, however, it does need to remain separate (I don't want to Emit this library for every time I create a dynamic assembly). Basically, I think I want to have my dynamic assembly to have a .assembly extern mscorlib in it's manifest save Static is place of the mscorlib.
Thanks
How can accomplish adding in this Static.dll reference so that when someone runs the resulting executable output of Dynamic that it can find the referenced types?
The reference will be added automatically. Note that normal assembly-probing rules apply when your dynamic assembly executes, so in order to find the assembly. You must (one of):
ship static.dll alongside dynamic.dll
put static.dll in the GAC (but please: don't do this!)
run dynamic.dll in a custom AppDomain with a custom probing-path configuration that lets static.dll be found
handle AppDomain.AssemblyResolve to provide static.dll
use something like ILMerge to fuse static.dll and dynamic.dll

How come I don't need to reference "System.dll" to use the "System" namespace?

I am working on an assignment that specified "Do not use any external libraries". So I created a c# application, and the first thing I did was remove all the dll's references by default... including "System.dll".
However, I can still add this to my code:
using System;
using System.IO;
I was just curious as to how come I do not need to have System.dll as a reference in my project to do this. Thanks!
mscorlib.dll includes items in both those namespaces.
You need to right-click your project > Properties > Build > Advanced... and check "Do not reference mscorlib.dll" to remove this reference.
Different assemblies can contribute to the same namespace.
Even if you don't reference System.dll, you are still referencing (implicitly) mscorlib.dll which contributes many types to the System namespace.
These references are probably defined in your Web.config or the Machine.config file so they're included by default.
These are the default libraries.I think your question is that "Dont use third party dlls"
Another thing to consider is, if you're compiling directly through the command line, a default set of switches, including default library references, is parsed by the compiler through the default response file (csc.rsp), located in the same directory as the compiler. The fact that you are able to import namespaces from the Base Class Library without explicitly referencing them at compile time is due to the fact that their containing assemblies are included in your program by default. To change this behavior at the command line, you can use the /nostdlib switch to force it not to include mscorlib.dll, or you can use /noconfig to have it ignore the entire default response file altogether. Also, I'm not too sure what you mean by system.dll, because the namespaces you mentioned are contained within mscorlib.dll. Also, I think by "external library", your instructor must have meant any 3rd party assemblies that would assist you in solving the problem. Anything that comes included with the .NET SDK would be more of a framework library. Unless your teacher is really harsh and wants you to reinvent the wheel :P

Debugging error "The Type 'xx' is defined in an assembly that is not referenced"

The full error is as follows:
The type
'System.Windows.Forms.Control' is
defined in an assembly that is not
referenced. You must add a reference
to assembly 'System.Windows.Forms,
Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b77a5c561934e089'.
and it points at the very first statement (an Debug.Assert line) in the very first class in a library project that doesn't need System.Windows.Forms (or so I thought). I know how to solve it: add the mentioned reference. But how do I find out what library is causing this error, or better, what part of the code triggers using the WinForms library?
Normally, you can add libraries that reference others, but you only need to add references to these others when they're actually used.
EDIT: Alternative solution
This or similar problems can also be resolved using the Binding Log Viewer Fuslogvw.exe from Microsoft's Framework Tools. It shows all attempts and successes of assemblies your application binds to.
I suspect there's no line of your code that's causing this, since you say you aren't making use of the System.Windows.Forms types and the compiler error isn't pointing to a (useful) line of your code.
What I think is happening is that you're referencing a library which has a publicly-visible method or property that either returns a System.Windows.Forms.Control or takes one as a parameter. It doesn't matter whether you actually end up calling that method/property, the fact that it's publically visible means that your own code has to be able to resolve all the types that the library is using. If the library only used System.Windows.Forms internally, you wouldn't be experiencing this.
It also means just looking at the dependencies of the assemblies you're depending on may merely narrow down the list of suspects, since there could be some assemblies that depend on System.Windows.Forms internally (no problem) and the one troublemaking assembly that has a public parameter / return value of a type from the S.W.Forms assembly.
My suggestion is you just set up an empty project without a reference to S.W.Forms, then add each of your dependencies in turn and try to compile after each one.
I had the same error.
The problem was that I used a reference to a project, which uses System.Windows.Forms inside.
The solution is to add a reference to System.Windows.Forms also in your project.
Use something like NDepend or Reflector or the Object Browser to check the dependencies of the assemblies you depend on.
I cannot think of any other way given the info above.

Categories