Internalize Class and Methods in .NET Assembly - c#

I have a set of multiple assemblies (one assembly is to be used as an API and it depends on other assemblies). I would like to merge all assemblies into one single assembly but prevent all assemblies except the API one to be visible from the outside.
I will then obfuscate this assembly with Xenocode. From what I have seen, it is impossible to internalize assembly with Xenocode.
I have seen ILMerge from Microsoft, but was unable to figure if it can do what I want.
http://research.microsoft.com/~mbarnett/ILMerge.aspx

I have used ILMerge from microsoft to internalize DLL's into a single assembled library. There is a useful GUI for using ILMerge called NuGenUnify. You can find it here.

I know Xenocode can merge assemblies into one but I am not sure if it will internalize other non-primary assemblies.
I have found the /internalize switch in ILMerge that "internalize" all assemblies except the primary one. Pretty useful!

I suggest you look at the InternalsVisibleTo attribute on MSDN.
You can mark everything in all the assemblies (except the API assembly) as internal instead of public, then reshow them to just your API assembly.
Having done that, using ILMerge should give you a single assembly with just the API classes visible.

There are some issues with ILMerge, but I think if you add optimisations + merge + obfuscation you're likely to create a highly complex situation for little benefit.
Why not have just one assembly, and make only your API public?
If you're always distributing them as a single assembly there's no reason not to just compile them as that. You'll get more benefit from compiler optimisations and it will be quicker to compile too.

Related

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.

strong name assembly - having to change thousands of assemblies

according to https://learn.microsoft.com/en-us/dotnet/framework/app-domains/create-and-use-strong-named-assemblies
A strong-named assembly can only use types from other strong-named assemblies. Otherwise, the integrity of the strong-named assembly would be compromised.
This is an issue because I would need to change all my thousands of assemblies, from weakly-named to strongly-named. This would take a long time, is there any way around this.
My use case:
I am building an application which will allow users to write C#, and execute it. I am doing this through an application domain. The application domain will compile the user code, in a partially trusted assembly. The user will be able to call a utilities assembly library. This utilities library, will be fully-trusted, and hence must be strongly named. This utilities library must be able to access the thousands of assemblies. The only way to do that now, is by changing all the assemblies to be strongly-named. which means I would need to add a AssemblyKeyFile attribute to each one.
Thanks
Dan
Yes, you are right strongly typed assembly can not have weakly-named assemblies in the reference.
There is a cool nuget package which signs unsigned libraries in the references:
https://www.nuget.org/packages/strongnamer

restrict add reference for an assembly

I have a framework which contains several assemblies. Multiple assemblies was created due to logical separation of code. This framework is supposed to be distributed to developer as well as end user. Developer are supposed to use few of framework assemblies to develop their modules. But all other assemblies are required to run the modules. Out of several assemblies, I want only few assemblies could be added to project reference and restrict other from being added to developer project references. In other words, I want developer should not be able to use types contained in assemblies which are not meant for plugin development. What is the best way to do that? I want to avoid passing some object to constructor of each type in those assemblies and verify them.
Can I take advantage of AppDomain or anything similar to that, which identifies type is being created by main app or module. If it is not main app, then throw exception or don't initialize. Any change in architecture is suggested.
One option would be to make the types within the "restricted" assemblies internal instead of public, then add InternalsVisibleToAttribute within those restricted assemblies to allow access to them from the other "framework" assemblies.
That way the end developer can still add a reference to the "restricted" assemblies (and probably should do so, in order to make sure they're copied for deployment) but won't be able to use any of the types within those assemblies.
EDIT: Another alternative might be to use ILMerge to build one assembly at the end - so it's a real unit of deployment, even though you originally split it out for separation reasons.
Yet another alternative would be to merge everything into one project and rely on code review, namespaces and common sense to pick up separation violations.
You can make all of the types in the other assemblies internal to prevent them from being ued outside their defining assembly.
You can use the [InternalsVisibleTo] attribute to make them visible to your other assemblies.

Two nested DLLs

We have a dll file; let's say X.DLL.
We are now writing another DLL, let's say "A.DLL" that uses some (very few) of the functions of X.DLL. We have no access to source code of X.DLL. Also, we don't want to give our clients X.DLL along with A.DLL.
Instead, we want to encapsulate X.DLL within A.DLL, so that distributing A.DLL will suffice.
Is it something possible?
Your help is appreciated.
Novice Coder
ILMerge
ILMerge is a utility for merging
multiple .NET assemblies into a single
.NET assembly. It works on executables
and DLLs alike and comes with several
options for controlling the processing
and format of the output. See the
accompanying documentation for
details.
You tagged your question with c#.
If these are managed assembly DLL's, which they will be if the code is c#, then you can do exactly what you want with ILMerge.
copy source code from x.dll to a.dll with required functions.
or split x.dll to two dll's
It is impossible to encapsulate one dll into another.
A way out may be if you can obtain a lib from the X.DLL vendors, and statically link to it with your code.
A hack out may be carrying the X.DLL as a resource inside you dll, then unpack and load in in the runtime.

Using different versions of the same assembly

I have a project where I simultaneously must use reports built in ActiveReports 2 and ActiveReports 6. Overall, it works ok, but some of the helper assemblies use the same name. For instance, to be able to export to PDF, both versions use an assembly called ActiveReports.PdfExport.dll. The corresponding assemblies are different, of course.
Note that I don't access the ActiveReports.PdfExport.dll directly - this is handled by the ActiveReports runtime.
I can't find a way to include both of them into the project. Is there a way? Is GAC the answer?
Creating separate external aliases for each assembly will help if you have type name collisions. For assembly name collisions, take a look at ILMerge; you can combine all related assemblies together. You'd create an assembly for ActiveReports 2 that combines all its required assemblies and another for ActiveReports 6.
GAC is one way, but Fusion resolution has a lot of flexibility in it that might suffice. Fusion will probe in the BaseDirectory for the assembly name .[DLL|EXE]. If not found it will probe BaseDirectory\Name.[DLL|EXE]\Name.[DLL|EXE]. So you might be able to get away with creating a folder named ActiveReports.PdfExport.DLL in your Bin folder and dumping the older version of the file in there.
Yes, you have to put both into GAC (this is what it's made for, in case of client assemblies).
My idea: create two libraries-helpers, reference each to appropriate assembly, register them into some kind of factory or manager and call specific one when you need.

Categories