Is there an equivalent to Python's ImportError in C# - c#

I'm putting together a code base for Unity3d with all sorts of common patterns. It will be imported into a project as source code not a compiled DLL.
Some of the code should only be compiled where a specific dependency (also installed as source code) is present. (In this case, Networking code should only be compiled if Photon is installed in the project).
I could just go through manually delete files that aren't required, however I would prefer some kind of automated way to conditionally compile classes.
If this where Python I could do something like:
try:
import MyLibrary
class MyClass(self):
...
except ImportError:
# library not imported
I know within a class I can use reflection to work out if a class is defined, but is there a way to do this at a higher level, i.e. with something like the pseudocode:
#if namespace_defined('ExternalDependency') // <-- how can I do this kind of check?
using ExternalDependency;
public class MyClass { ... }
#endif

In C#, there's no chance that you could include an using clause in a code file as part of a project which doesn't reference the assembly that contains the imported namespace, thus, you won't be able to perform that check.
An using of a namespace which can't be located in any of referenced assemblies will produce a compiler error (i.e. Are you missing a project reference?).
In other words, C# encourages developers to be sure that all dependencies are available at compile-time.
Actually, if you want to perform different actions in your code depending on some configuration, environment or whatever, it seems like you'll need to stick with inversion of control design pattern.

Related

Only compile certain parts of my program depending on the calling assembly

I have three assemblies. One assembly contains code that relies on the 'NETWORKING' COM service. This service is not available on some machines and I would like to only compile the code depending on the assembly that consume this assemblies.
I have two assemblies that rely on this shared assembly: One GUI and one CLI assembly.
I tried to use the #define preprocessor check, but this only works within the same assembly (right?).
The obvious yet time consuming choice would be to extract the code into a separate assembly.
I was wondering if there is another possibility. Just like defining symbols or something like. The CLI assembly would define the CLI keyword and the GUI assembly would define a keyword 'GUI'.
In the shared assembly I could then use something similiar to
#if CLI
using NETWORKLIST;
#endif
Is this somehow possible in Visual Studio / C#?
Assemblies are independent, so unless you're using the same "build" each time, the short answer would be "no, you can't do that". The most appropriate approach here is to move the relevant code to another assembly - which is probably less than 3 minutes work. Alternatively: just ignore it and accept that a few extra bytes of disk space are being used unnecessarily - it won't hurt.

Can I redirect a c# class to another dll?

Here is my problem. There is a game engine with a core library core2.dll which has a class C in it.
It is a windows class with a c# wrapper.
I want to use mainly all the classes from core2.dll except for one class which I want to use the class from the previous version of the library core1.dll
If you try to call the class from core2.dll it has a 'deprecated error message'.
I think the class is pretty self contained. (Lets say it is some math functions for example) So my thoughts are to include both core2.dll and core1.dll in my project but somehow make the class C only from core1.dll.
Any thoughts on how (if at all ) to achieve this?
If you need to replace part of the code inside core2.dll then you can decompile both using ildasm, change required pieces inside core2.dll and compile it back again.
Run x64_x86 Cross Tools Command Prompt for VS 2017 and execute
ildasm core1.dll /OUT=core1.il
ildasm core2.dll /OUT=core2.il
REM open il files with text editor, find classes in core1.il and replace them in core2.il
REM note, that there might be no core2.res
ilasm core2.il /RESOURCE=core2.res /DLL
This will work absolutely fine if dll is not signed. Even better - you assemble to code so ilasm will ensure your code will work in the runtime. Runtime incompatibility is a pretty annoying issue with binding redirects...
Make sure you don't violate any licenses and copyrights.
you need to use external alias for both dll
here is an example:
https://www.learningsomethingnew.com/how-to-use-two-versions-of-the-same-dll-in-the-same-project

C# Adding a reference to a class in another project without referencing the project

I have two projects:
ProjectMain (class library)
LibraryProject (class library)
ProjectMain is a class library that should only be compiled as a singular library, no referenced libraries. I require a static class reference from LibraryProject BUT I don't want the LibraryProject assembly to be compiled together with the ProjectMain assembly.
I've tried 'link references' in visual studio but this is no solution as the library assembly is always compiled with the main assembly.
There are clear standard solutions to this issue but I am severely limited by the existing implementation requirements. Only one DLL can be compiled without any of the dependent assemblies being in the execution folder, GAC, private path, reflection etc.
The exact limitations are as follows:
Assembly executed in a sandbox from a third party provider, it only supports adding a single assembly with no direct references/reflection etc (it's horrible but my hands are tied)
We would like to handle the code organisation as best possible which means following standard best practices, unfortunately, due to the above limitation that's proving difficult.
What I would like to know is if there is a way to reference a class within another project without also compiling/using that referenced classes assembly. Possibly a method where the compiler 'embeds' the referenced class at compile time.
If your sandbox does not allow loading other dlls in AppDomain, load it yourself by embedding it. You can use Costura.Fody for this purpose, it is easy to use/install, just reference it from nuget.
Of course, embedding it in every scenario is madness and often comes with completely obscure bugs, which often solvable only by enabling traces in regedit.
So, in your case I would create two projects:
MyDll.csproj //it is my original project, with perfect code design and etc. Lovely.
MyDll.Sandbox.csproj //this one is the same as MyDll.csproj, except it is compiled with additional Costura.Fody reference, into single dll (every reference is put inside)
This way you just need to maintenance that MyDll and MyDll.Sandbox files are the same.

Wrap namespaces into conditional symbol (#if)

I'm writing a simple library for my program.
I wrote a lot classes, however after everything done I realize that I need to wrap the files with specific namespaces into #if conditional.
for example, I wrote an alternative implementation of System.Numerics under .NET 2.0:
namespace System.Numerics
{
public class Vector2
{
//.. implementation here
}
}
However, it's only apply if USE_ALTERNATIVE is defined, so if I target into equal or greater than .NET 3.5, I only need to remove USE_ALTERNATIVE from compilation symbol
The class should be like this:
#if USE_ALTERNATIVE
namespace System.Numerics
{
public class Vector2
{
//.. implementation here
}
}
#endif
however, writing #if to all classes under my custom implementations is really tedious work.
is it possible to accomplish this with find and replace that available in Visual Studio?
OK. There is actually a really easy way to do this, and it does not require you to actually use any #if conditionals at all.
Instead, simply put all of your shim classes (that's the technical term for what you're doing) in the same class library project. This will put them all in the same .NET assembly.
Then, in the referencing project, have two different build configurations, targeting different versions of .NET. In the list of references for the 2.0 config, include the library. In the 3.5 config, simply leave it out.
EDIT: Another solution you can use that uses #if conditionals is to wrap the using directives in your client program (instead of your shim classes themselves). That way, you only have to include one #if directive inside each client class that uses your library (and I would assume that your entire project only encompasses one namespace, correct?)

How to force a C# root namespace throughout project files for when none is coded?

I want to force a root namespace on the contents of any .cs source files that don't have their contents wrapped in an explicit namespace. In other words I want to keep classes and other namespace-level structures out of the default namespace.
(Working inside a Windows .NET environment with Visual Studio)
In the following example, I want to force the Car class into the MotorIndustry namespace by default even though it has no explicit namespace coded.
Vehicle.cs (has namespace)
namespace MotorIndustry {
public class Vehicle {
// ...
}
}
Car.cs (no namespace/default)
public class Car : Vehicle {
//...
}
Is there a way to accomplish this "root namespace" modification behaviour through project settings in Visual Studio, AssemblyInfo.cs file or some other means?
My understanding is VB.NET has a feature like this but C# acts differently?
Some context about why am I asking this: I have hundreds of classes and the programmer forgot to wrap the namespace around some. When I reference the assembly from other projects it's polluting the default namespace with classes that end up causing some ambiguous situations.
Use ReSharper to move the classes into the proper namespace. In fact, version 5.0 (still in Beta) allows you to correct namespaces globally.
The other way to do it is to make the other developer fix the code.
It sounds like you are trying to replicate VB.Net's project namespace feature in C#. This is not a supported feature of the C# compiler or IDE. You will not be able to create one by modifying a project file. You will need to add the namespace to every file in the project either manually or via a tool.

Categories