3

I have a C# library with lots of internal functionality exposing only a few public classes and interfaces. I would like to share this code between several projects, and each project may need to extend the internal classes with subclasses.

I don't like the idea of making all these classes public in order to create a common library. I think it exposes them too much to easy decompilation and break the design.

Is the only real option to create a copy of the source code and keep those files in sync between projects? Or is there some way I can share code and still get a single library for each project exposing only the few intended public interfaces and classes?

I'm using Visual Studio 2010.

UPDATE

Thanks for the clarification regarding decompilation and "private" access. I think I could consider applying an obfuscator over several input libraries, all together, hopefully obfuscating even their public connections.

From the design standpoint, seems like the answer is definitively to use friend assemblies.

Miguel Posada
  • 33
  • 1
  • 4
  • 1
    You will get little to no protection from decompilation by doing this. Some purists would say you are stretching OOP principles in doing what your trying to do - it's leaky encapsulation. – Joshua Enfield Feb 29 '12 at 00:39
  • 1
    Access modifiers have no effect on decompilation. You can use any reflector app to extract your C# code from the DLL. Don't waste your time with that aspect. – Timeout Feb 29 '12 at 00:39
  • That's a fair point, in this case, it could make more sense to use an obfuscator that is able to take several input libraries and obfuscate them together even their public connections, is it possible? – Miguel Posada Feb 29 '12 at 00:45

5 Answers5

8

You may want to look at doing friend assemblies:

http://msdn.microsoft.com/en-us/library/0tke9fxk(v=vs.80).aspx

[assembly:InternalsVisibleTo("someassembly")]
Joshua Enfield
  • 17,642
  • 10
  • 51
  • 98
  • can you please have a look at it here http://stackoverflow.com/questions/21301360/share-properties-from-child-app-to-base-project – Goofy Jan 23 '14 at 07:05
3

Create a new project. File > Add > Existing. Select the existing code files. Hit the drop down on the Open button and choose Link.

making classes internal vs public has absolutly zero bearing on its ability to be decompiled.

Sam Axe
  • 33,313
  • 9
  • 55
  • 89
  • Your last statement "internal vs. public" is not totally true. Most Obfuscators will aggressively rename/obfuscate internal classes/methods - whereas they won't rename public classes. – Steve Feb 29 '12 at 00:38
  • This solution has some issues yes, but in my opinion they are less annoying than the issues one would face using the friend assembly mentioned in numerous other posts. – Sam Axe Feb 29 '12 at 01:42
  • 1
    @b1naryj, how would this solution throw off his namespace convention? If all he's doing is linking the files needed, preserving everything intact, as long as he doesn't also hold a ref to the project where the code actually resides, imho this is a much better solution than friend assemblies :) – Jason Feb 29 '12 at 02:54
  • @b1naryj If anything one can create an entire directory/subdir tree that will resemble the namespace desired. I think we're being overzealous with the whole directory structure solution thing here. The gods at MSFT do the same thing, look at System.Web dll, it has Microsoft.Runtime.Hosting and System.Configuration, not only System.Web.... :) One added plus of this approach imho, is my app won't load an entire assembly because I need one class from there, and I can make edits to the same file without having to rebuild the other project (unless the change is needed in other places) – Jason Feb 29 '12 at 14:38
2

You are looking for "friend" assemblies: http://msdn.microsoft.com/en-us/library/0tke9fxk(v=vs.80).aspx

Steve
  • 31,144
  • 19
  • 99
  • 122
2

You can accomplish this using the InternalsVisibleToAttribute on your assembly

Justin Pihony
  • 66,056
  • 18
  • 147
  • 180
0

I think it exposes them too much to easy decompilation

You're in for a shock then, as even private classes in an assembly can be trivially de-compiled and used to create a public implementation.

"Breaks the design" is another issue. If you want to use this code from separate projects, than making them public is exactly the right thing to do. If you do not want to make them public, than think about what interface this project really wants to expose to the outside that will still accomplish what you need... and build that api and make it public.

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
  • The problem is there are two "public" users: myself when I'm doing other projects, and the actual final user. – Miguel Posada Feb 29 '12 at 00:48
  • I think the key here is the OP's use of the qualifier "easy". As per my comment on "Boo"'s post - any reputable Obfuscator will mangle/rename internal and private classes/methods, where as they won't do the same for public ones. Does that mean an obfuscated assembly can't be decompiled - no - but it does mean that making your way through the renamed/mangled ones is more difficult. So - "too easy", yes. – Steve Feb 29 '12 at 01:05