user settings for a dll; and a 2nd ? about Friend Assemblies

T

Terry

I have a windows form application for which I have built a number of custom
user controls. Thinking that it would be a good idea to keep them in a
seperate project (maybe not such a good idea) that is what I did.
I have decided to make some of the behaviors of some of the user controls
subject to "user settings". So, I added some settings to the user control
library and set about trying to manipulte those settings from the .exe that
references the dll.
Hmmmmm...
Of course I could add a class with properties to 'wrap' all the settings and
expose them, but that seemed like a waste. Thought that there must be a
better (easier) way to do this.
I tried to add a class and a readonly property to the control library
project to return the My.Settings like this...

Public Class UserSettings
Public Shared ReadOnly Property Settings() As My.MySettings
....
but get an error saying I can't expose the type 'My.MySettings" outside the
project ...
....since the MySettings Class is declared as Friend.

So, one way to get around the problem is to go into the Settings.Designer.vb
and change it to Public.
I wonder if that is such a good idea?

I also discovered that if I used the concept of friend assembly and declared
the .exe to be a friend assembly, then I could get at the entire My namespace
of the dll.
Is this a better idea?

Now while on the subject of friend assemblies...
I had put all these custom controls in a different project just because it
seemed cleaner. I can't forsee using them in any other project and thought
that maybe I could hide them from the outside world by once again declaring
the .exe as a friend assembly and changing the scope of each control to
Friend. The only problem is, is that they then disapear out of the toolbox!
So, at design time, you can't create any more or them.
Ok, so I changed them back to Public and changed the constructors to Friend,
and the designer started complaining and giving me error messages.
So, I guess I have to either live with customers being able to get at my
custom control library or I have to move them back into the original .exe
project.
Any other ideas?
 
A

Alex Clark

Hi Terry,

The My.Settings is generally accepted to be for .exe's only. This is
because if your DLL was shared and in use across multiple different
applications, it would generally be non-intuitive to save the settings
specific to the DLL.

Imagine if you had a special TextBox control which saved its font setting in
the last app it was used in. This might be some fancy word processing app
you've created, and the user might be using a scripty, cursive-esque font to
do a nice formal document with.

If they then open up a different app that uses that same specialised TextBox
control (say a very simple Notepad style app) they'd then be presented with
the same font because it was saved as a setting specific to the control
rather than per application. It would be far more intuitive if the
word-processing app saved the scripty font setting, and the notepad app
saved a fixed-width font setting, allowing users to change each one
independently as they required.

So in general, My.Settings is only available to EXEs, and with good reason!
So, one way to get around the problem is to go into the
Settings.Designer.vb
and change it to Public.
I wonder if that is such a good idea?

Not really. The code is generated by the designer and is subject to being
re-generated without warning, so you could find yourself having to make the
modification over and over. It's not particularly good design practice
either...

I'm not sure what you mean by "Friend Assemblies" either? Access modifiers
(Friend/Public/Private/etc) are, at the highest level, declared on Classes
rather than assemblies.

If you have no requirement to re-use the controls in other applications or
expose them to other programmers, why not just keep them inside your main
(EXE) project?
So, I guess I have to either live with customers being able to get at my
custom control library or I have to move them back into the original .exe
project.

If you're concerned about others gaining access to the controls, changing
them from Public to Friend isn't the way to go about it. If *you* can
reference a DLL and use the controls contained within it in your EXE, then
*anyone* can in exactly the same manner. If you need to prevent this, the
first step would be to implement some sort of licensing whereby the controls
cannot be used unless a specific license key is provided/present.

Failing that, and if you decide to just embed the controls in your EXE
project and declare them as friend, you're still not safe. Even though they
cannot be used by another application referencing your EXE now, your code is
still subject to decompilation - meaning someone could reverse-engineer your
EXE, copy out all the code for your user controls and use them in his/her
own app.

Fortunately, VS provides you with an obfuscation tool (Dotfuscator) which
will allow you to effectively encrypt your code, making it very difficult to
reverse engineer.

Kind Regards,
Alex
 
T

Terry

Hi Alex,
Thank you for your reply. I think friend assemblies are new to 3.5 and
you may not be familiar with them. It allows you to name 1 or more other
assemblies that will then have access to friend classes and methods in this
assembly. It looks like this...
Imports System.Runtime.CompilerServices
<Assembly: InternalsVisibleTo("MyFriendAssembly")>
Also, as far as the user settings for the dll, they don't actually work as
you described. When the .exe modifies the settings for the dll and saves
them, they get saved inside the .exe's user settings as a new group. It
looks like this inside the .exe's user.config file...
<section name="MyDllName.My.MySettings"
type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0,
Culture=neutral, PublicKeyToken=b77a5c561934e089"
allowExeDefinition="MachineToLocalUser" requirePermission="false" />

So, the values I set in this .exe are not seen by the .dll when it is used
by another .exe. Perty cool huh?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top