Solved

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

Posted on 2015-01-08
14
256 Views
Last Modified: 2015-01-16
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!
0
Comment
Question by:ShineOn
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
14 Comments
 
LVL 33

Expert Comment

by:ste5an
ID: 40540401
Well, add a LoadConfiguration(string fileName) method to load an arbitrary settings file using the ConfigurationManager class.
0
 
LVL 35

Author Comment

by:ShineOn
ID: 40540800
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
 
LVL 80

Expert Comment

by:David Johnson, CD, MVP
ID: 40541020
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
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 40
ID: 40541654
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
 
LVL 35

Author Comment

by:ShineOn
ID: 40541665
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
 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 40542253
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
 
LVL 33

Expert Comment

by:ste5an
ID: 40543939
"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
 
LVL 35

Author Comment

by:ShineOn
ID: 40544820
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
 
LVL 33

Expert Comment

by:ste5an
ID: 40544826
You should already have a class in your library code, otherwise you have nothing to use.
0
 
LVL 35

Author Comment

by:ShineOn
ID: 40545017
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
 
LVL 33

Accepted Solution

by:
ste5an earned 500 total points
ID: 40546473
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
 
LVL 35

Author Comment

by:ShineOn
ID: 40550028
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
 
LVL 33

Expert Comment

by:ste5an
ID: 40550046
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
 
LVL 35

Author Closing Comment

by:ShineOn
ID: 40554471
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

Featured Post

Back Up Your Microsoft Windows Server®

Back up all your Microsoft Windows Server – on-premises, in remote locations, in private and hybrid clouds. Your entire Windows Server will be backed up in one easy step with patented, block-level disk imaging. We achieve RTOs (recovery time objectives) as low as 15 seconds.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article describes two methods for creating a combo box that can be used to add new items to the row source -- one for simple lookup tables, and one for a more complex row source where the new item needs data for several fields.
In Part II of this series, I will discuss how to identify all open instances of Excel and enumerate the workbooks, spreadsheets, and named ranges within each of those instances.
In Microsoft Access, learn how to use Dlookup and other domain aggregate functions and one method of specifying a string value within a string. Specify the first argument, which is the expression to be returned: Specify the second argument, which …
In Microsoft Access, when working with VBA, learn some techniques for writing readable and easily maintained code.

730 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question