Obsolete library class - c#

What is the best way to prevent C# programmer from using particular library class?
Class is from external assembly so it is impossible to use [Obsolete] attribute on it. I tried to use Resharper custom patterns but it seems not to support generics types.

Patch the library method/class (there are several plugins for Reflector) - add DeprecatedAttribute, or modify its code to throw an exception, for example.
You can also make a special unit test which runs at CI server and fails if a particular deprecated item usage indicated.

You can disassemble the library with ildasm, add [Obsolete(true)] attributes and reassemble with ilasm.
You might be able to find some assembly edit tool, like Reflexil together with a trial of Reflector.
Note that if you edit an assembly you loose all signing and stuff.

Related

Dynamically created class to cs file?

I am creating a complex class with AssemblyBuilder that Im later creating objects from. There is however uncertainties in how this class is really contructed. So is there any way to write this dynamicly created class to a cs file for inspection?
I can get the dll file written to disk but I need the cs file.
You can decompile managed .NET dll to C# code using
DotPeek by JetBrains (free, sources are closed)
ILSpy open source project (MIT license sources are available at github)
Reflector by Red Gates (Paid tool, sources are closed)
JustDecompile by Telerik (free with open source decompilation engine available at github Apache License)
There is also a Microsoft's ildasm tool.
If you need to write custom tool you can download open-source code and give it a try.
Do you have a requirement to use AssemblyBuilder? I'm asking because AssemblyBuilder wont allow you to see the generated class without using a decompiler and if the class you´re generating is quite complicated, the decompiled code wont be of good quality.
You are almost in the same situation if you use Reflection.Emit because it generates low level IL.
If you really need to see the source code that you're generating dynamically your best option is CodeDom. Here's an example How to: Create a Class Using CodeDOM
You might be able to kill two bird with one stone with Roslyn (aka ".NET Compiler Platform"). You'll need the package Microsoft.CodeAnalysis.CSharp.
First, you can use the SyntaxFactory class to generate syntax nodes, which you can combine into larger structures (members, methods, classes, namespaces, compilation units).
You can also get a nicely formatted representation of your syntax nodes with ToString() or ToFullString() (with correct indentation and line breaks and everything), which is what you were originally looking for.
There are quite a few tutorials online on how to use this API (like 1, 2), and there's the Roslyn Quoter website that can convert a piece of C# code into SyntaxFactory calls.
Second, you can then use the resulting CSharpSyntaxNode to create a CSharpSyntaxTree, which you can compile into IL with the help of CSharpCompilation (after all, Roslyn is the reference C# compiler).
If you want, you can even emit the generates assembly into a stream, get the assembly's binary data from there, and load your newly created assembly into your currently executing assembly, and dynamically instantiate the types you just defined.
You need to use the .NET reflection.
Ildasm.exe cannot help you because it will not create the .cs file you need.
So either the ILSpy is the open-source .NET assembly browser and decompiler from the SharpDevelop team or dotPeek from Jetbrains.
Depending on the platform you may also check Mono Cecil. Cecil is a library written by Jb Evain to generate and inspect programs and libraries in the ECMA CIL format.
If you need speed JustDecompile from Telerik is a free tool for .NET assembly browsing and decompiling that claims to be 10x faster than competitors.
All these tools lets you take an existing compiled assembly (.dll or .exe) and easily browse the symbols it contains, and then just as easily decompile the assembly language back to readable C# and IL.

Inject a C# file in a DLL

I have a DLL written in C# for which I don't have the sources. I have tried different C# decompiler to modify the DLL, but they all give me errors in my attempts to recompile with the modifications, I suppose due to IL decompilation limitations. Is it possible to add a .cs file to the root of the DLL in order or inject a method to add a functionality ?
PS: This is not intended to hack a software but to create a mod of a game which requires DLL modification.
Your best approach may be to just create a wrapper project around the dll to add the functionality that you want. Your code could them reference the project instead of the dll. As long as the classes aren't sealed you should be able to inherit from them.
Modifying code you don't have access to probably isn't a good idea to begin with. Especially if the dll could be updated in the future.
You can also create a new DLL with the same namespace. This might make things look as if they're in the same location, but it's not the best practice and it could be confusing since namespaces are expected to match the project/dll name.
Benjamin's solution with the wrapper seems reasonable.
The Reflexil plugin for .NET Reflector could inject a method or a class in a DLL as illustrate in a video by its creator.
It prevents decompilation-compilation errors as it just injects IL code in the assembly.
To install this plugin follow these steps.

Weave third party dll with fody

I would like to write a Fody plugin that will allow me to weave a third party dll.
Is it possible?
Reading the documentation and the source code from different plugins, I haven't found any way to do so.
It appears that fody only enables to weave the assembly that is referencing the plugin (using the ModuleDefinition property populated at build time).
As fody relies on Mono.Cecil I think it is technically possible, but it does not seems like my use case has been considered at all.
Tanks

Adding Resharper code annotation to own code in a non-invasive manner

I want to flag one of my methods with the StringFormatMethod attribute so Resharper syntax highlights it.
I was able to do this by referencing the JerBrains.Annotations assembly and adding the attribute.
However I find this to be a very invasive way to do this. Not everybody here uses JetBrains and it will require committing the .dll to subversion, adding the dependency and littering the code with something that is specific to a particular IDE, which I hate.
I read about the "external annotations" feature, but I wasn't able to do it. I'm not sure if I did it wrong or if it's simply not supported for a project inside the solution (i.e not a compiled assembly reference).
So is there a way to add a code annotation to a method in the project in a non-invasive way?
P.S this is the method:
using System;
namespace MyLib
{
public static class Assert
{
public static void That(bool condition, string format, params object[] #params)
{
if (!condition)
throw new Exception(string.Format(format, #params));
}
}
}
And this is the contents of
C:\Program Files (x86)\JetBrains\ReSharper\v7.1\Bin\ExternalAnnotations\MyLib.xml:
<assembley name="MyLib">
<member name="MyLib.Assert.That(System.Boolean,System.String,System.Object[])">
<attribute ctor="M:JetBrains.Annotations.StringFormatMethodAttribute.#ctor">
<argument>format</argument>
</attribute>
</member>
</assembley>
Just to sum up possibilities:
You reference nuget Jetbrains.Annotations, and DO NOT define JETBRAINS_ANNOTATIONS:
Such annotations are useful only for developers working with source code, they are not compiled in your binary (Conditional statement is used) and they are not visible when referencing your dll. You can even add developmentOnly="true" attribute to Jetbrains.Annotations in packages.config, so by default it would not be treated as dependency.
You reference as above but define JETBRAINS_ANNOTATIONS:
now you have real binary dependency and Jetbrains.Annotations.dll must be either distributed with your library or it must be downloaded as nuget dependency.
You copy annotations with internal checked (so client code would not use them), into "YourLib.Annotations": They then embedded into your lib and available for other developers even when they use only binary version.
You provide external annotations: for bigger libraries/more attributes this can also consume 40k, it is separate file, and generally it is less trivial to create/consume.
I personally went with third option (for shared libraries, projects usually just use nugets)
You don't have to reference the assembly to add annotation attributes. As per the documentation, you can go to ReSharper/Options/Code Annotations, copy the attribute implementations to the clipboard, and paste them into your own source, where ReSharper will use them. You can even change the namespace they're in if you'd prefer not to have JetBrains in your assembly.
I don't know whether you'll have any luck using external (XML) annotations for source code, though. I get the impression they're only for existing binaries. That said, I think that decorating your source with attributes is quite valuable as a source of documentation for yourself and other developers.
Don't know if it helps, but the element name <assembley> is misspelled (unless they actually used that in the schema). Should be <assembly>.

An automated way to rid a project of a Contract dependency

I am trying to build a NSpeex solution for Windows Phone application. The problem is that a codeplex NSpeex page provides a Silverlight version of the library, but it throws a run-time exceptions, since the code contracts are used in the library, that are not yet present in Silverlight for Windows Phone.
I will go ahead and remove all the lines of code that make use of Contract class. For this I will just do a text search on all the classes in the Visual Studio Project. Is there a better solution. For example, to somehow prohibit the use of some namespaces, so that the VS compiler would show me all the dependency points?
I haven't looked at the source code for this project, but what we usually do in this situation is to either build stub classes that stand in for the missing classes (especially if they are attributes) or remove code through conditional compilation.
The decision on which approach to use depends on the complexity of the problematic code.

Categories