Re: Internal access modifier is not working the way I thought it would.



There is no such thing as an "internal assembly" in .NET. That is, once
you declare something public within a DLL then any program can include
that DLL as a reference and use that class / method / field / etc.

Stated another way, the highest level to which access modifiers apply
is the assembly. If something is publicly visible outside a DLL
assembly then it is publicly available to any code that references that
DLL.

JT wrote:
Hey Dave,

Here's my problem. The programmers I'm referring to, I have never met,
may never meet, and may pass on the DLL to people I didn't expect. The
point is to provide this DLL to anyone and everyone who wants to use
it, as long as I can control how they use it. So while I would like to
think that it wouldn't end up in the hands of someone who wants to
cause harm or does so accidentally, I can't count on that.

I'm confused about what you're suggesting. Maybe there's an aspect I
haven't thought of. As far as I know (might not be as far as I think),
there is no way to include the web service in the DLL that I want to
distribute. It must refer to the web service on its web server and
therefore, can't be encapsulated as an additional class in the DLL's
namespace. If I'm wrong, then I'll need explicit instructions on how
to do that. Yes, I was hoping to make the instantiation of auMethods
an internal because I can do that with individual methods within
ProvideWorkFlow.dll, but it doesn't seem to honor that request for the
web service. For all I know, it may not be just web services, but also
instantiated DLLs as well. I haven't tried that yet.

Maybe I'll try marking my class as internal inside the web service, but
I am wondering if that will prevent the ProvideWorkFlow DLL from being
able to use it.

Tricky stuff. I'll let you know what I find.

JT

Dave Sexton wrote:
Hi,

Your example only shows me that you have marked a member variable as internal:

internal AccesUtils.AccessUtilities auMethods;

However, the class definition is not marked internal and that's why it's
available to be instantiated externally:

namespace ProvideWorkFlow.AccessUtils
{
public class AccessUtilities
{
}
}

should be:

namespace ProvideWorkFlow.AccessUtils
{
internal class AccessUtilities
{
}
}


The problem is that once AccessUtilities is marked as internal it can't be
referenced by the ProvideWorkFlow.dll either. That's why I recommended that
you include the web service in your ProvideWorkFlow.dll instead of a separate
assembly. Then, you can make the web service internal to the ProvideWorkFlow
assembly.

If you require AccessUtilities to be located in a separate assembly then the
easiest solution is to just keep it public and tell your programmers to use
the interface supplied by ProvideWorkFlow.dll classes.

Although, you could use some design pattern to hide the implementation behind
an abstract factory and an interface so that programmers would be more
inclined to use the interface provided by ProvideWorkFlow.dll instead of
creating their own; however, they would be able to implement their own and
directly access the web service if they really wanted.

To be perfectly honest, I don't think it's a good idea to try and shield your
programmers from using the wrong tools, but instead educate them to use the
right ones. I highly recommend fostering open communication. Pair
programming, peer review and unit testing can help to shine a light on
"strays". So don't take the latter choice lightly - use at your own risk!

--
Dave Sexton

"JT" <jt@xxxxxxxxxxx> wrote in message
news:1162572698.713040.156160@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Thanks Dave,

Actually, I mis-spoke. The classes within the web service's namespace
(AccessUtils) are able to be instantiated from within the end program.
Below I am going to indicate Intellisense options text between pound
signs, #. Also, AccessUtilities will represent the class defined
within the AccessUtils web service. So for instance, if I have a
reference to ProvideWorkFlow.dll and then, in the program, I begin to
instantiate methods and forms from ProvideWorkFlow, I will see
something like the following:

ProvideWorkFlow.InitialContactForm frmInitContact = new
ProvideWorkFlow.InitialContactForm();

ProvideWorkFlow.
#
InitialContactForm
CustomerFeedbackForm
CustomerProcessingMethods
{} AccessUtils <-- web service namespace
FollowUpForm
#

ProvideWorkFlow.AccessUtils.
#
AccessUtilities <-- class containing WebMethods
AssignCustomerToAgentEventArgs
AssignCustomerToAgentEventHandler
StartProcessingCustomerEventArgs
StartProcessingCustomerEventHandler
...
#

ProvideWorkFlow.AccessUtils.AccessUtilities auMethods = new
ProvideWorkFlow.AccessUtils.AccessUtilities();

auMethods.AssignCustomerToAgent(CustomerID, AgentID);


In the previous example, it would be completely inappropriate for the
programmer to have direct access to the AssignCustomerToAgent() method.

To address your other statement, the reason this needs to reside in a
web service is because the database is on a web server that is, well,
who really knows where? So that is why the ProvideWorkFlow.dll
references and instantiates the AccessUtils.AccessUtilities class. So
in ProvideWorkFlow.dll, I make the following declaration:

internal AccesUtils.AccessUtilities auMethods;
...
auMethods = new AccesUtils.AccessUtilities();

Then, the methods in ProvideWorkFlow.dll call the appropriate
AccessUtilities methods in a way that won't violate the business rules.

I reallly thought that would do what I needed. Any other suggestions?

Thanks,

JT

Dave Sexton wrote:
Hi,

You are correct that object definitions and members defined with the
internal
modifier will only be visible to the assembly in which they are defined.

If you are able to construct internal classes or call internal methods then
I
assume you are doing so from the same assembly. (BTW, namespaces cannot be
instantiated)

Your best option would probably be to build all of it into the
ProvideWorkFlow.dll, since that is the public interface, making objects and
methods private or internal as needed.

--
Dave Sexton

"JT" <jt@xxxxxxxxxxx> wrote in message
news:1162557017.358866.195660@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Here is the overall structure I will be referring to:
End-program
ProvideWorkFlow.dll
Forms and methods that properly manipulate calls to methods in
AccessUtils
AccessUtils (a web service)
Hide.dll
methods and data I want to remain hidden

I have a DLL, Hide.dll, that contains methods that I want to handle for
end-programmers. The methods in Hide.dll are declared as public. I
have a web service, AccessUtils, that provides access to these methods
by acting as a "go-between". It uses identical method signatures and
just returns the result of the method calls in the DLL. The WebMethods
are declared as public.

Example:
[WebMethod]
public string GetSensitiveInfo(string pKeyValue)
{
Hide.Utils HiddenUtils = new Hide.Utils();
return HiddenUtils.GetSensitiveInfo(pKeyValue);
} // end of GetSensitiveInfo()

Furthermore, there are programmers that need this functionality but
don't need, and shouldn't have, direct access to the methods in
Hide.dll, or even directly use the methods in the AccessUtils web
service. I have a DLL, ProvideWorkFlow.dll, that contains public
Windows Forms and methods that will make the appropriate calls to the
AccessUtils web service in the appropriate order and thereby enforce
the "work flow", although I'm not sure I would call it a true work flow
model. In ProvideWorkFlow.dll, I declare AccessUtils as an "internal"
to try to make its methods available only inside this
ProvideWorkFlow.dll assembly. However, if I act as a programmer that
would be using ProvideWorkFlow.dll, when I go to instantiate one of its
forms, I see that the forms are available, but also the namespace for
the AccessUtils web service is available to be instantiated. I tried
declaring AccessUtils as private in ProvideWorkFlow.dll but it was
still visible and available. I thought the whole purpose of declaring
something as internal was to prevent it from being visible outside the
containing DLL (assembly).

How do I need to set this up so that the end programmer only has access
to the forms and methods declared in ProvideWorkFlow.dll?



.



Relevant Pages


Quantcast