Solved

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

Posted on 2015-01-08
14
225 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
14 Comments
 
LVL 32

Expert Comment

by:Stefan Hoffmann
Comment Utility
Well, add a LoadConfiguration(string fileName) method to load an arbitrary settings file using the ConfigurationManager class.
0
 
LVL 35

Author Comment

by:ShineOn
Comment Utility
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 78

Expert Comment

by:David Johnson, CD, MVP
Comment Utility
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
 
LVL 40

Expert Comment

by:Jacques Bourgeois (James Burger)
Comment Utility
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
Comment Utility
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 74

Expert Comment

by:käµfm³d 👽
Comment Utility
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 32

Expert Comment

by:Stefan Hoffmann
Comment Utility
"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
Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

 
LVL 35

Author Comment

by:ShineOn
Comment Utility
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 32

Expert Comment

by:Stefan Hoffmann
Comment Utility
You should already have a class in your library code, otherwise you have nothing to use.
0
 
LVL 35

Author Comment

by:ShineOn
Comment Utility
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 32

Accepted Solution

by:
Stefan Hoffmann earned 500 total points
Comment Utility
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
Comment Utility
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 32

Expert Comment

by:Stefan Hoffmann
Comment Utility
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
Comment Utility
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

Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

Join & Write a Comment

Whether you’re a college noob or a soon-to-be pro, these tips are sure to help you in your journey to becoming a programming ninja and stand out from the crowd.
Although it can be difficult to imagine, someday your child will have a career of his or her own. He or she will likely start a family, buy a home and start having their own children. So, while being a kid is still extremely important, it’s also …
In Microsoft Access, learn how to “cascade” or have the displayed data of one combo control depend upon what’s entered in another. Base the dependent combo on a query for its row source: Add a reference to the first combo on the form as criteria i…
In this fourth video of the Xpdf series, we discuss and demonstrate the PDFinfo utility, which retrieves the contents of a PDF's Info Dictionary, as well as some other information, including the page count. We show how to isolate the page count in a…

744 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

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now