I have a system in place which applies calculations to a set of numbers (the specifics aren't really relevant). There are a number of sets of calculations which can be applied by the system users and new sets are added frequently. Currently when a new set of calculations need to be added to the system they are added in to the code base and a new version of the system released. I'd like to be able to add new calculation sets into the system without having to release a whole new version and also to have these new calculations become visible to system users automatically. Currently a new function is created for each set of calculations and a record containing the appropriate function name is added to a system table. These records are visible to system users (function names are aliased of course!) who then select them from a list. The system uses the Eval() function to run the appropriate calculations.
This is a VB6/Access app that I inherited and am currently re-writing in VB.NET and SQL Server.
Does anyone have any advice on how best to do this?
Since you're redoing it in .Net, just put the calculations in plugins. Use reflection to load and examine these assemblies at runtime and present the user with functions.
Divil has a good (but fairly old now) article on writing plugin based applications. It will help you out: http://divil.co.uk/net/articles/plugins/plugins.asp (+ it's in VB.Net)
If you do it this way, all you have to do is drop a dll into the right directory and it just works.
If you are using a standard set of mathematical functions you can use use allow the user to write their own mathematical functions in a textbox.
Then use a grammar parser such as :TinyPG on CodeProject
With this you can then break down the expression into :Reverse Polish Notation
This can then be easily stored and recalled from the database in a varchar field.
Once this is setup you won't need to republish the application unless you need to add new mathematical functionality.
Related
I'm fairly new to VB.NET, and I've mainly been doing ASP programming up 'til now, and I have a pretty simple question.
I'm creating a program that will copy a selected file to a selected directory, and I want to store recent files/dirs so that they can be selected from a combo box. I was planning to just create a settings with "files" and "dirs", and just store the strings as | separated values (since that's an illegal file character).
Is there anything wrong with this approach, or are there any better methods?
I think your approach is fine as it seems to be simply a local cache of recent directories. You can persist the data in the application at the module level(create a module with a public object essentially is a global variable) but it goes away when the application is terminated.
This article is using a similar approach to what you were thinking although the example is in C#
Supposing I have a merge module that installs a file "MyFile.txt" to a certain location, and that I wish to use that merge module, however I want to supply a different copy of "MyFile.txt" from the one supplied with the merge module.
Is it possible to do this? (And for bonus points how can I do this using Wix)
Update: Roughly speaking MyFile.txt is part of a package up component of installable items that we provide to others, they then comine these components with their own to produce an installer.
In the ideal world they would only need to add new files to the output, however this is a replacement for an existing system where they currently have the ability to modify or even replace items (suce as MyFile.txt) in the end installer, and so without the ability to do the same with the merge module the migration path will be difficult.
The packaged up component doesn't need to be a merge module if there is a better solution, however merge modules seemed like the sensible choice and in all other respects provide a very nice re-usable package of installer logic.
It's possible but every technique that I know is a bit of a hack and doesn't scale very well. Can you tell me more about what type of file MyFile.txt is and what the intent of the different flavors of the file? Usually my goal is to never have the same filename twice ( darn component rules ) and then design variation points to support the needs. Sometimes upstream changes to the application are required to do this correctly.
I've inherited a collection of largely undocumented ssis packages. The entry point package (ie: the one that forks off in a variety of directions to call other packages) defines a number of variables. I would like to know how these variables are being used, but there doesn't seem to be an equivalent of "right click/Find All References"
Is there a reliable way to determine where these variables are being used?
A hackish way would be to open the dtsx file in a text editor/xml viewer and search for the variable name.
If it's being used in expressions, it should show it and you can trace the xml tree back up until you find the object it's being used on.
You can use the bids helper add-in thats gives you visual feedback on where variables are used in your package. Thats makes it very fast and easy to detect them.Besides that, it offers several other valueable features.
Check out: http://bidshelper.codeplex.com/
I am maintaining an old VB6 application, and would like to include SQL scripts directly in part of the project. The VB6 application should then extract the text of this script and execute it on the server.
The reasons for this approach are various - among others, we want to deliver only an updated executable rather than a complete update/installation package. Hence, the SQL scripts need to be compiled into the application just like a resource file. And, obviously, one has to be able to get at the content from code, in order to send it to the database server.
Does anyone have a good way to do this?
The simplest solution is to just create a VB module with the scripts as strings.
If you want to use a resource file instead, you can do that too. You can associate a resfile with a VB project (I don't remember how to do this directly in the VB IDE but the VBP file supports a ResFile32 parameter).
EDIT: It seems like the issue here is mostly about formatting -- you don't want to store SQL queries as one long string, but formatting the query nicely inside VB is tedious because you have to add quotes, add string concatenation operators to join the lines together, etc.
I would recommend placing the SQL in a text file and formatting it in whatever way you like. Write a script that will take the text and convert it into a VB module. The build process would be modified to always apply this script first before compiling the application.
For scripting, use your favorite scripting language; if you don't have a favorite scripting language, this is an easy enough task that you could do it in VB, C#, or any other language. If it were me, I'd probably use awk (gawk) or Python.
If you want to use a resource (.RES) to store your SQL, go to the menu:
Add-ins > Add-in Manager...
and select VB 6 Resource Editor. Configure the add-in to be loaded and to load at startup.
From the editor add-in, VB provides a simple interface to add resource strings. You will refer to these using the provided constant values. To load the strings at runtime, use the LoadResString function:
Public Const SQL_INSERT As Integer = 101
Dim strSQL As String
strSQL = LoadResString(SQL_INSERT)
(replace "101" with the constant value of the string you wish to load)
Just another thought on your approach. Because I find myself tweaking the program's behavior or UI for customers I might be in the middle of a change that either is not ready or has not yet been tested and approved. So if I have properties that change from time to time, but I want to maintain control of, for instance connection settings to our ftp server, I will create a resource only dll exposing my properties and use a resource file in the dll to supply the values. When my network manager changes something on the ftp server I change the strings in the resource maanger, recompile the dll and release just the updated dll. I'm sure there are many more solutions, but that is how I do it. If you don't think you might have to change your SQL scripts at the same time you are changing you exe this probably only complicates your work. It has worked well enough for me that now this is pretty much standard for me.
I've been tasked with maintaining an application originally written in VB6. It has since been imported into VB .Net and to say the least the code is anything but Object Oriented. The code is riddled with classes which contain nothing more than Public Shared attributes(variables) and methods(functions), the result of which restricts the application from opening more than one project at a time.
A project consists of a XML file which contains general project settings, as well as the location to an Access database which contains other project related data. Over the years the format of the XML file has been modified, and an update and versioning strategy has been adopted. The chosen strategy performs an update upon open whenever an old version is encountered. Thus far, updates have only consisted of rearranging data within the XML file or making database schema changes and moving data from the XML file to the database.
Having quite a bit of background in OOP it's easy for me to see that a project should be a self contained object which other objects interact with. However, I fail to see how to apply the chosen update strategy in OOP.
The problem of implementing the chosen update strategy in OOP has kept me from using OOP as of yet. If anyone has experience with such a task, or recommendations on how to proceeded I'd appreciate any assistance you can provide.
Build a class which reads the XML file in, and provides properties/methods/etc based upon the data in that file. When the class writes the XML file back out, have it format in the manner needed for the new version.
So, basically, the class will be able to read in the current version, plus all the older versions, but it will always write out the new version.
Data would be held in internal variables of the class, rather than having to scan the XML file every time you need something.
Adding a VERSION node to your XML file will also help in this case.
You might have answered your own question when you used the word strategy (i.e. the Strategy Design Pattern).
Possibly you could:
Create a project class that knows nothing about conversions but accepts a strategy object.
Create a hierarchy of classes to model each possible conversion strategy.
Use a factory method to build your project object with the right strategy
I don't understand why this is a troubling problem. It could be solved in any number of ways.
If you want to do a full object oriented enterprisey type thing, you could take any subset of the following solution:
Create an interface IProject which
describes how other objects interact
with a project.
Create the current implementation of
Project which implements IProject
and can read and write to the
current version.
Extend Project for each past
version, overriding the xml and
database read methods and having the
constructor call write when these
classes are instanced
For extra enterpriseyness, create a
ProjectFactory, which detects the
version of the file and instanciates
the correct version.
If further versions are needed,
rewrite the current Project to do
the same thing as past projects,
accessing the new version of Project
with all the reads and then calling
write.
The advantage of this solution is that you can continue meandering about with different versions and each new version only requires the ability to be updated to from the previous version, with all previous versions cascading up to the second to last version.