views:

952

answers:

4

Hello, I asked this question to multiple people and until now I do not have an answer.

ASP.NET C#

Project tree (files and folders):

> (ROOT) 
>
> Class MyAccess (namespace myproject.core)
> 
> (Directory John)
------> Class MyJohn          (namespace myproject.core.John)
------> Class JohnSecret      (namespace myproject.core.John)
------> Class OtherJohnSecret (namespace myproject.core.John)
> 
> (Directory Paul)
------> Class MyPaul          (namespace myproject.core.Paul)
------> Class PaulSecret      (namespace myproject.core.Paul)

How can I use (public, private, protected, internal) ????? to have have this behavior:

  • class MyJohn sees and can create objects from all the classes inside John folder (all his secrets)
  • class MyPaul have the same behavior but inside Paul folder
  • All this secrets CAN NOT be used OUTSIDE this folders.

Examples:

  • MyPaul can use all his secrets, and he can communicate with the classes MyAccess and with MyJohn.
  • MyPaul, MyJohn, MyAccess will be public or internal
  • MyAccess can not use PaulSecret.


Solutions that I do not like:

  • BAD Solution 1

Make John secrets as protected and heritage one MyJohn

Example:

> protected JohnSecret
> internal MyJohn:JohnSecret

bad because if i've 100 class secrets I'll need to have something like:

> internal MyJohn:JohnSecret1, JohnSecret2,....,JohnSecret100
  • BAD Solution 2

Have classes inside classes:

> internal class MyJohn {
> 
>        internal string DoSomething(){}
>        
>        private class JohnSecret{}
>        private class JohnSecret2{}
>        private class JohnSecret3{}
>
> }

It's not good because, once again, if I've 100 secrets I'll have a HUGE file, I can't split that code in different source code files.


Can anyone give a good solution?

I appreciate :)

Thanks a lot.

+4  A: 

I think if you change your "Directory"'s to new Projects and then include them as References in your root application you might be able to achieve what you want to achieve.

Once you've created new Projects, setting the accessors as internal will limit the scope to that assembly only.

Neil Fenwick
Thanks for your help, indeed that is also other solution, however is this case is not scalable, because if I've secrets of more than one person (lots of directories, John, Paul, Sarah, Tim, etc...) I'll need to have many projects and if I need to use interfaces/abstract classes, etc... I'll need to have a common project to share this.
emanyalpsid
Perhaps you should ditch the "person as a class" metaphor and give some more real classes? Perhaps then you would get answers more to your liking. In most peoples worlds, persons like this are handles as instances of a class, not separate classes.
Lasse V. Karlsen
+3  A: 

You should go with the second solution you propose. For the visibility requirements that you have it is most appropriate for JohnSecret, OtherJohnSecret, et. al. to be defined inside the MyJohn class.

If your desire is to split the class file in multiple files, you can use partial classes to achieve that and still maintain the visibility requirements that you have.

For example:

> (Directory John)
> File "MyJohn.cs"
public partial class MyJohn
{
}

> File "JohnSecret.cs"
public partial class MyJohn
{
    private class JohnSecret
    {
    }
}

> File "OtherJohnSecret.cs"
public partial class MyJohn
{
    private class OtherJohnSecret
    {
    }
}
paracycle
+1  A: 

C# has the following access.

  • public - everyone can see it
  • private - only things inside the class can see it
  • protected - only things inside the class, or inside derived classes can see it
  • internal - only things inside the assembly (dll or exe) can see it
  • protected internal - only things inside the class or derived classes can see it, and only if they are in the same assembly

You have only 2 options:

  • As Neil mentioned, you can use internal, and split your code up into 2 assemblies - one for John and one for Paul.
  • As you have already mentioned, you can use private, and nest all the JohnSecret classes inside the outer John class. paracycle's tip of using partial classes makes this reasonably nice.

Note: to make multiple assemblies you must make multiple projects inside visual studio.


From a pragmatic point of view, does it really matter if the directories are fenced off from each other like that? There are no security benefits in using access modifiers as anyone can always use reflection to easily call your private/internal methods anyway.

The main benefit it gives you is keeping clutter out of your way when coding, but you've already put them in different namespaces, which should help with clutter anyway.

Orion Edwards
I tested the partial classes the way "paracycle" said and it's working fine.About the reflection aspect you talked about: I used the tool "Red Gate's .NET Reflector" and yes, I can see all my private classes and core. I am also able to Disassemble. and I can see the code .... :SThis showed me that there isn't a way to protect our code? How can I sell a program and do not allow a smartguy to clone my code?
emanyalpsid
Actually, `protected internal` is `protected` *or* `internal`, so it is visible to anything in the same assembly, the class itself and its derived classes, regardless of which assembly they are in.
Bojan Resnik
+1  A: 

Dryadwoods,

After reading your comment on Orion Edwards' answer, I think you are mixing up the concepts of:

  1. structuring your project so that its manageable for you to edit and build on it, and
  2. protecting your code from reverse engineering

If its the second that you are actually trying to achieve then look into Dotfuscator or any other C# obfuscation tool. What that does is mix up your code at compile time to make it very difficult to reverse engineer, but allows you to code as you normally would.

Neil Fenwick
Hello Neil, the concept of protecting the code from reverse engineering only came after trying the tool "Red Gate's .NET Reflector".My first question (structuring the code) came when we've code that will be developed by a team (multiple people coding -> CVS control) and sometimes with the Visual Studio's IntelliSense we can access one class (in some other code directory) that should not be used directly. This is why I asked who we can avoid this.In fact I am not mixing up both concepts :)Anyway, thanks for your contribution and pointing obfuscation tools :)
emanyalpsid