There are a couple of options to prevent the user from reverse-engineering your assembly. Let us discuss the following techniques.
1) Native Image generation
2) Strong-naming the assembly
3) Hiding the Implementation via a web service
Native Image Generation
One technique you may try is to create a native image of your assembly. This is done via the ngen tool that comes with .NET. This tool doesn't work with CIL source files; rather, it takes a .NET assembly and transforms it into a native assembly. For example, you can create a native image of AI.dll as follows:
The tool creates a native image of the assembly, but it puts the result into the Native Image Cache (NIC). You can see what's in the cache by using the /show argument of ngen:
Unfortunately, the results aren't what you might expect. The problem is that you still need the original assembly for the client code to run properly. ngen essentially creates implementations of your methods, but the metadata is contained in the original assembly. If you try to run an assembly that uses AI.dll after you employed ngen on it and deleted (or renamed) the source AI.dll, the client will throw a FileNotFoundException.
The runtime will always load the CIL-based assembly, but it's smart enough to use the native implementations if they exist in the NIC. Therefore, you can't distribute a native image without the regular assembly. Someone will always be able to reengineer the code like I did before, and if you rename the resulting assembly and target the client to use this new assembly, you can prevent the runtime from using the native implementations.
Strong-Naming the assembly
The best you can do with strong-naming your assembly is that you can prevent others from reverse-engineering your code and putting your brand on it. It doesn't prevent others from at least being able to see the underlying code.
Hiding the Implementation as Web Services
If your clients have high-speed Internet access, another option available is to make them Web services. Clients can access the assembly's functionality, but they can't get the physical assembly itself. Also, if a bug did occur in your assembly, fixing the offending code means that all clients get the fix at one time.
Of course, there may be situations where this is not feasible. For example, if you were writing a high-performance graphics engine to compete with DirectX, you probably don't want the method invocations to occur over HTTP. However, if you know that you must protect your resources, then keeping them off the client's machine may the safest way to do so.
This is basically a technique in which a tool will take input, like source code or a PE file, and create output that makes it very difficult for reverse-engineering tools to discover what the executable is doing. However, it will not change the expected behavior of the code, and it may make loading times quicker.