I have inherited a project that has class libraries written in VB.NET, some of these have ".settings" files and the others have a ".dll.config" file to store connection strings. What is the difference between these 2 methods?
EDIT: In what scenarios would I prefer one over the other?
They're basically the same thing - or strongly related, anyway. A settings file gives you strongly-typed access to entries in an app.config file, and keeps them in sync. When you compile, the app.config file is copied to the bin folder with the name of your assembly.
Note that, if you modify the .config file by hand, you can lose changes if the settings file overwrites them. In VS2008 it will prompt you, so you can choose to sync them.
I think that .settings is application wide, while the .dll.config files are specific to the assembly they are named for.
".config" files are at the core of .NET configuration system. They store the actual configuration data. In the early .NET framework, if you wanted to extend the configuration system to handle your custom configuration data, you had to do this manually. "Settings" file is a feature that allows you to visually define configuration options and use them to create a strongly typed class. This class can then be used as a method to read and manipulate the configuration data specified in application's ".config" file at runtime. They also provide some neat features automatically, such as defining per-user or per-application configuration options. They greatly reduce the hassle to manually extend the configuration system.
Related
I have several .csproj files that I will be importing a common .targets file into, to extend the build process. The projects are in different directories. The .targets file is in the solution directory. How do I refer to the location of the .targets file to import it? There's a solution directory property, but this doesn't work if the developer just builds a project. What do I do? I am using .NET 4.5 and Visual Studio 2015.
As you figured a project doesn't know about a solution it's contained in, and arguably it shouldn't. So there's not much you can do to programmatically figure out where, from the project's point of view, a totally unrelated file is situated. Apart from scanning the entire filesystem for it. There are some alternatives:
rely on a proper directory structure. You do this already anyway, since you use a solution which also needs to find projects in a fixed location. So suppose you have a main project dir with projectA/a.vcxproj, projectB/b.vcxproj and solutionDir/ab.sln and solutionDir/my.targets then in a and b just <Import Project="$(MSBuildProjectDirectory)..\solutionDir\my.targets"/>
require a property (or environment variable) which is set to the location of the targets file and then use <Import Project="$(SomeDir)\my.targets"/>
put your targets file in a 'known' msbuild location like the Importbefore/ImportAfter directories, mentioned here for instance.
I've used all of these at one point and in the end the first is in my opinion the better one: you just have to stick with a directory convention - you need that anyway for projects spanning mulriple directories or with common shared stuff - and that's it. For example we have a ton of common msbuild files and they're in a single repository. Starting a new project always comes down to creating a directory, cloning the common files dir and adding a new project dir. That can it turn easily be automated, also works well on typical CI servers. The second option is also doable, but it relies on a properly setup environment which is less 'self-contained' and gets really messy if developpers start entering the variable in the machines' global environment variable settings, and in the local ones, and so on. Similar problems with the third one but worse since now there's only one correct location.
I have a Class Library, which is called by a VB6 client and VB.NET client. If the Class Library is called by the VB.NET client then there are settings in the app.config for Log4Net (http://logging.apache.org/log4net/). If the library is called by the VB6 code then there is no logging at the moment.
The question I have is about the app.config. If I have an app.config in the VB.NET client (Windows Forms) and the class library, then I assume that:
If client is Windows Forms then
Use VB.NET App.config
ElseIf client is VB6 then
Use Class Library app.config
Is that correct. I have done some research on MSDN, however I cannot find anything explicit and hence the question.
I don't think class libraries support app.config files directly - they merely use the app.config / web.config of the assembly that forms the process - so the console app, service, WinForms App etc.
app.config files are useful only to CLR executable assemblies and they are automatically loaded when the application runs.
If your executable is not a managed application (application developed using VB6 I assume), app.config is useless because CLR won't get loaded into the process (since it is not a managed app).
If your assembly is managed but not executable (class library), it is useless (useless in terms of execution, otherwise it can be used to copy the contents to an executable project's app.config).
Class library uses the config file of its host, so even if the class library project has a config file, it will not be reference at run time. Instead it will look for the config file of the host executing the DLL.
To avoid recompiling the code after the build to update a variable values like Development DB and Production DB, etc. You can either use setting or hard code a path in your program to look for a 'config' file. I use an XML file, with a key-value pair. I then load and read it to a list, or dictionary that i can use in my application like a 'config' file.
Now when I deploy, I can simply change the 'config' file in the hardcoded location in my dll to whatever environment without the need to rebuild the class library.
I've an desktop application that implements Serializable class, but now I'm translating it to an web app with servlets, I use Netbeans for this work,I have the following code:
InputStream input = ClassLoader.getSystemResourceAsStream(file_input);
Where file_input is an bytecode fyle from an object serialized before, I don't know where I should put this file because in the desktop application I put it in the same dir where I had my classes.
(I have the file, I don't need to create it).
First of all, don't use ClassLoader#getSystemResourceAsStream() in a Java EE web application, ever. Instead, use ClassLoader#getResourceAsStream(). I would also put big question marks around using ClassLoader#getSystemResourceAsStream() in a Java SE desktop application, for sure if it's intended to be distributable, but that aside.
The ClassLoader ultimately loads resources from the classpath. So all you need to do is to make sure that the file is placed in one of the paths which are by default covered by the webapp's runtime classpath, or to add the new path to the file to the webapp's runtime classpath through a server specific configuration setting, such as shared.loader property of Tomcat's /conf/catalina.properties.
One of the default paths covered by the webapp's runtime classpath is the /WEB-INF/classes folder of the WAR. From IDE project's perspective, just drop the file in the root folder of the "Java Source" (src) folder, there where you have all your Java packages and classes. The IDE will take care that it ultimately ends up in /WEB-INF/classes of the built WAR file.
I by the way still assume that you are not creating the file from inside the webapp, as you explicitly told. That wouldn't work. If you actually need to have write access as well, you're going to need an absolute disk file system path instead. You can always make it configureable by providing it as a VM argument or environment variable, for example.
This is for Struts 1.x (I'm using 1.3.10).
I've noticed that Struts is unable to pick up resource bundles in the ApplicationResources.properties file if it is not placed somewhere in the default classpath (e.g., com.abc.SomePackage).
For instance, if I put the ApplicationResources.properties file in a custom folder /WEB-INF/strutsResources and configure the struts-config.xml thus:
<message-resources parameter="/WEB-INF/strutsResources/ApplicationResources"/>
I've read that the resources need to be on the classpath so I've also tried adding the /WEB-INF/strutsResources folder to the classpath. It still does not pick up the resource keys.
I've double-checked that the strutsResources folder is actually deployed to the server (I'm using Glassfish v3), so the file is there, it's just not being parsed.
P.S.
If you're wondering why I'm trying to do this, I just wanted to organize my code a little better ("better," IMO). Since the ApplicationResources.properties file is not really a class, I wanted to place it in a resources folder by itself.
I've checked that placing the ApplicationResources file in a package in the src directory works just fine.
Ultimately, the answer is yes. You can play some interesting games by configuring a custom className and/or factory and get messages however you want (including from a database) and so on. This allows you to customize whatever you want*.
I agree the resources aren't a class, but putting them on the classpath is a common practice, and allows resources to be loaded as a resource, e.g., from inside a jar. I'm sympathetic, but I'd leave it as-is.
*Like reversing all the text; a fun prank to play on your co-workers and QA department.
Its best leave it on the classpath.
It's stadard practise to include properties files on the classpath, especially if you're planning on packaging it up in your WAR/EAR. You're keeping it under WEB-INF so you gain no benefit from moving it off the classpath, and you'll just confuse other developers who have to work on the project and you've had to put a hack in to make this work.
If you want to keep your files external to your deployable WAR/EAR then that's a valid reason for not using the classpath. Typically this will require some configuration as part of your deployment to specify where the file is to reside.
For example specify the location using
a JVM argument (e.g. -Dprops.file=/config/myapp.properites)
lookup from a JNDI resource
use a PropertiesFactoryBean if you're using the Spring framework (I
use Spring's ApplicationContext with Struts 1 MVC)
read properties from a database writing your own
ApplicationPropertiesDAO class that initialises itself durnig your
applications bootstrap process (e.g. Spring application contact,
Servlet in web.xml, Listener in web.xml, etc)
In our WCF solution we have one ConsoleHost (console application not class library) project and one WasHost Project. We use the Consolehost hosting for Dev environment and WAS hosting for production.
Now there are a number of .config files that are included using "include uri=file://services.config" in the Castle section of ConsoleHost project. I don't want to make a copy of this services.config file in the WasHost Project.
Is there a way to include files from other projects without making local copies of them? Or happy to hear other better ways of doing this.
Thanks
Ravi
You could do this a couple of ways.
One is to simply add a link to the source file from both projects as described here.
Alternatively you could embed the config into one of the common assemblies (Build Action=Embedded Resource in the file properties) and then use Castle's ability to include embedded resources. E.g.
<include uri="assembly://AssemblyName/xxx.config"/>