Need to read settings from a file in vb.net class lib

I am modifying an existing program which is a standalone class library exposed to COM, for reference by MS-Access VBA.

The program has several hard-coded variables in the classes which I want to be able to load from a file.

Since it is a class library and not a start program, app.config can't be used, because class libraries defer to the app.config values from the calling exe.  

Since ms-access VBA doesn't have .net app.config capability, I need to be able to read from an external file that is not part of the managed-code world.

Can anyone point me to workable examples of code snippets to accomplish this file read from a class library process?  It has to read the file at the time the library is invoked, so the variables get set before the functions are called.

Thanks!
LVL 35
ShineOnAsked:
Who is Participating?

Improve company productivity with a Business Account.Sign Up

x
 
ste5anConnect With a Mentor Senior DeveloperCommented:
E.g.

Imports ClassLibrary1

Module Module1

    Sub Main()

        Const CONFIG_PATH As String = "C:\Temp\myClass1.config"

        Dim myClass1 As Class1 = New Class1

        Console.WriteLine("From Library: " & myClass1.DoSomething)

        myClass1.LoadConfiguration(CONFIG_PATH)
        Console.WriteLine("From Library: " & myClass1.DoSomething)

        Console.WriteLine("Done.")
        Console.ReadLine()

    End Sub

End Module

Open in new window


with

 
Imports System.Configuration

Public Class Class1

    Private someMember As String = "default"

    Public Function DoSomething() As String

        DoSomething = Me.someMember

    End Function

    Public Sub LoadConfiguration(configFile As String)

        Const SECTION_NAME As String = "MySection"

        Dim fileMap As ConfigurationFileMap = New ConfigurationFileMap(configFile)
        Dim configuration As Configuration = ConfigurationManager.OpenMappedMachineConfiguration(fileMap)
        Dim section As AppSettingsSection = CType(configuration.GetSection(SECTION_NAME), AppSettingsSection)

        someMember = section.Settings.Item("myKey").Value

    End Sub

End Class

Open in new window


and

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
	<configSections>
		<section  name="MySection" type="System.Configuration.AppSettingsSection" />
	</configSections>
	<MySection>
		<add key="myKey" value="myValue" />
	</MySection>
</configuration>

Open in new window

0
 
ste5anSenior DeveloperCommented:
Well, add a LoadConfiguration(string fileName) method to load an arbitrary settings file using the ConfigurationManager class.
0
 
ShineOnAuthor Commented:
intellisense says that LoadConfiguration isn't a member of System.Configuration.ConfigurationManager.  Do you have a code snippet to show what you mean?

I read somewhere that if you use the office tools you can use a settings file, but I haven't found quick & easy documentation on that, and I haven't done any office-specific programming... and I also saw (but don't recall where) code samples of how to read settings from a not-managed-code-app.config file, which is what I'm shooting for seeing as Access VBA, as far as I'm aware, wouldn't invoke an app.config to load settings to a COM-enabled DLL it's referencing.
0
What Kind of Coding Program is Right for You?

There are many ways to learn to code these days. From coding bootcamps like Flatiron School to online courses to totally free beginner resources. The best way to learn to code depends on many factors, but the most important one is you. See what course is best for you.

 
David Johnson, CD, MVPOwnerCommented:
hard-coded variables in the classes which I want to be able to load from a file.


When a program is compiled a hard-coded variable is changed to a pointer to a location that holds the variable contents
0
 
Jacques Bourgeois (James Burger)PresidentCommented:
Define static (Shared) variables and initialize them in a static constructor.

Public Class YourClass

	Public Shared YourVariable As Integer

	Shared Sub New()
		YourVariable = 10    'Replace this by reading in a file where you defined the values of the variables
	End Sub

End Class

Open in new window


The static constructor is called automatically when you use the class in any way for the first time, so the following line is sufficient to retrieve your variable value. You do not even need to instantiate an object, simply call the variable on the class:

result = YourClass.YourVariable

Be careful however. If you do instantiate objects on the class, they all share the same variable. If you change the value of the variable from one of the objects, you change it for all the other objects.  To prevent that, you can declare the variable as private and define a ReadOnly property to access its value:

Public Class YourClass

	Private Shared YourVariable As Integer

	Shared Sub New()
		YourVariable = 10	'Replace this by reading in a file where you defined the values of the variables
	End Sub

	Public ReadOnly Property YourProperty As Integer
		Get
			Return YourVariable
		End Get
	End Property

End Class

Open in new window

0
 
ShineOnAuthor Commented:
What I am doing is taking a class lib which is used by an executable program, and chopping out just the one class that is needed to be referenced from an ms-access VBA to perform a few functions that cannot easily be written in vba, specifically the creation of an xml soap file to put to a web service to update a separate system.

The exe that uses the class lib accesses that system and pushes info into the postgreSQL linked tables in the ms-access app, in addition to running some evaluations on the postgreSQL tables and pushing automated updates to the external code.

The class lib the exe uses has variables which are set by the exe's app.config - connection string, web service url, login information for the web service, paths to work folders for the xml soap files which are built, to xml templates, to response files from the web service request, to the log writer, to the smtp server address for email notifications and the like.

Some of those values are not needed in the class I am creating for the outbound xml push functions for the vba app, but some are - and since ms-access vba doesn't play nice with .net (unless I missed the memo) unlike excel or word where you can put an app config file in the excel or word path and have that provide the app config to ConfigurationManager for the class lib, I am looking for an alternative to replace that for this particular scenario.  The reason for wanting to feed this info from a file is the usual - so testing can use test-environment values and production implementation can use production-environment values, without having to create both a test and prod version of the code and maintain a duplicate set of slightly different executables and libraries.

This application is not likely to be around forever, so I don't even want to look at reading configuration data from a database.

Oh, for the days of DLL hell and .ini files... ;)

The path I am currently exploring is using the project settings to set the variables' values, which should (if I can do it right) generate a dll-specific config file.
0
 
käµfm³d 👽Commented:
intellisense says that LoadConfiguration isn't a member of System.Configuration.ConfigurationManager.
What version of .NET does your library target, and is it one of the Client Profiles?
0
 
ste5anSenior DeveloperCommented:
"add a LoadConfiguration" means that you need to create a public method in the COM-visible code to tell your library what file it should load. In this method you can use the ConfigurationManager to use standard XML configuration files.
0
 
ShineOnAuthor Commented:
kaufmed, I am targeting .Net 4.5.1.  Client profiles have been discontinued starting with 4.5, according to devnet.

ste5an, do you have a code snippet or a devnet article you can point me to?  I'm not clear on how to implement a class that will make ConfigurationManager not expect the library to be inheriting the config file from an app.

Any thoughts on the use of settings.settings?
0
 
ste5anSenior DeveloperCommented:
You should already have a class in your library code, otherwise you have nothing to use.
0
 
ShineOnAuthor Commented:
Of course I have a class in my library code.   I guess I misunderstood, because you're "speaking" in short bursts with background info omitted because you're assuming that everyone should know what you know.  That's why I'm asking - because I don't.  "Back in my day," Experts were expected to be more verbose and helpful  when giving their advice.

I thought you were saying I needed to create a class for this LoadConfiguration method.  Are you saying I just add a new com-exposed method to my existing class?  How will that method be called to bypass the normal, app-inherited config?  Why should it be COM-exposed?  Shouldn't it be declared shared?  Do you have any code examples to explain what you're trying to say?

I assumed "another class" because that's what some of the articles I've read have suggested, to create a "data reader" class in the same project.  Problem is, many of these articles are written for C# and not VB, so their examples don't necessarily apply, and I don't know enough C# to be able to translate the syntax even if they did.
0
 
ShineOnAuthor Commented:
Thanks for the examples,  ste5an.

So I need to create a module in my class lib project, which will do the loadConfiguration event, and that module will call a subroutine in the class lib vb which defines the loadConfiguration method?  Or am I reading it wrong?

Can I assume that the sub main() in the new module means it will run whenever the class lib is invoked, forcing the reading of the configuration from file?
0
 
ste5anSenior DeveloperCommented:
No, you don't create a new module. My Class1 is your COMVisible library class. You just add the LoadConfig method to load an arbitrary config file. The LoadConfig() method is called in VBA/Access.
0
 
ShineOnAuthor Commented:
Thanks, ste5an!

The config is loaded from the external program call to the new method, not on class lib first use, so it's not exactly what I was looking for, but it should work!
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.