Typically we keep our config values in web.config/app.config and for the environment global config varialbes (and not application specific) in server machine.config file.
When deploying an object to the GAC where is the best location to keep these config type values? It seems that the best location would be a linked resource file.
Does anyone have any experience/recommendation with this approach? (sample code?)
thx
The configuration values need to be in the application configuration of the executing assembly. It is the responsibility of the application to have the configuration values so that your assembly will have access to them when it is loaded into the AppDomain.
I've had a need for assembly-specific config files (as opposed to executing assembly config files) in the past.
For an assembly in the GAC, it is possible (but not recommended) to physically copy a config file to the assembly dll folder.
The solution I've used for creating a config file that can be shared across assemblies regardless of AppDomain is a a simple registry entry for my application that defines a shared config file location. This way, any assembly can retrieve configuration settings from a shared location, regardless of which executing assembly launched it. (especially useful for scripting - otherwise, you'd have to deploy a config file named wscript.exe.config in the windows\system32 folder - UGH!)
if you dont care of having specific configuration for each application using your dll you can place the configuration in the machine.config file inside the framework folder.
%systemRoot%/Windows/Microsoft.Net/Framework/[Version]/Machine.config
Related
I have a remote SQL Server database, wrapped with Entity Framework inside a dll.
When I reference that dll from my main application, I get a runtime exception stating "missing connection string in app.settings file" or, if I manually add the connection string, "no Entity Framework engine found".
If instead, I install EF from NuGet ALSO in my main application, the referenced dll works perfectly.
Now, the reason why I created and referenced the dll was to detach my business layer from the persistence layer, but if I need anyway a reference to EF for my application to work, I'm loosing the advantage of the dll wrapping.
What should I do?
EDIT:
I can't add a dependency from my main app to EF simply because the user of that dll will be a client outside .NET, such as an Excel or Matlab instace
You will have the same issue with all your dependencies. You must distribute multiple DLLs and make sure they get loaded. See
See Resolving Assembly Loads
The AssemblyLoad event allows you to take over the assembly loading process for your AppDomain, and you can find the dependent assemblies on disk outside of the normal search locations (which are dependent on the host .exe location), or download them, or unpack them from assembly resources in your main .dll.
See also How to load an Assembly in a SSIS script task that isn’t in the GAC
The dll NEVER has it's own config file that it accesses to read settings such as connection strings. Although your code to read the config information may be in an assembly, the config file is owned by the host process, so an entry for connection strings MUST be present in the Host processes config file.
In your scenario, it sounds like on the remote sever it will be SQL server that acts as the host process. On your local machine, the host process (your .exe or website, IIS Wp3 ) will act as the host process. Your local process WILL require the connectionstring setting in web.config / app/config.
In VS, when we add a reference to an assembly project, all of the dependent .dll's get compiled and placed in the top level applications bin folder. If you simply reference a .dll file from your application, these dependent .dll files are not placed in the bin folder. This is what you are experiencing here with EF.
It is possible to encapsulate EF functionality inside a .dll file, but the .dll files which make up EF itself, MUST be available to the host process. You don't need to add a NuGet reference to your main application. By referencing the project that you .dll is built from in your main application, the EF engine will be compiled to the bin folder of your main application.
Once you have built and deployed your main application with a project reference to your assembly, all the required files will be in the folder from which you execute your application. You can then make changes to the .dll source and just update the .dll binaries in the application folder, providing the changes do not break contracts etc eg. method signatures.
Problem is that my settings from "app.config" is not being gotten in class library project.
Can "app.config" be used in applications only and not in class libraries?
You should add the config settings to the project that is using the class project. ie If you have a project 'MyProject' that references 'MyClassProject' then the app.config settings should be placed in the 'MyProject' project
Application configuration files contain settings specific to an application. This file contains configuration settings that the common language runtime reads (such as assembly binding policy, remoting objects, and so on), and settings that the application can read. The config file is optional, if it does not exist environments such as ASP.NET will fall back to the machine.config file stored in the .NET system directories to get machine wide defaults.
Think about it like that. If you class library has some custom settings then it should have a config to deal with it.
By design of .NET framework when you access Application configuration with default means - .NET runtime supplies you with data from app.config of entry assembly (an EXE file that references your class library).
Application Configuration of class library can be accessed in following way (code should be placed in project of class library - in order for Assembly.GetCallingAssembly().Location to return proper path):
ExeConfigurationFileMap classLibraryConfigurationMap= new ExeConfigurationFileMap();
classLibraryConfigurationMap.ExeConfigFilename = Assembly.GetCallingAssembly().Location + ".config";
Configuration classLibraryConfiguration = ConfigurationManager.OpenMappedExeConfiguration(classLibraryConfigurationMap, ConfigurationUserLevel.None);
I have an ASP.NET application which is adding up .NET assembly in its reference. The assembly is a private assembly and it has a config file with some keys under <AppSettings>.
Now the problem is when I am debugging my ASP.NET application the assembly is not loading the app.config file.
I observed that under the property of referenced assembly I have Copy Local=true.
Can anyone please help or point out if i am missing some basics?
You need to collect all pertinent settings into the web.config file of the main ASP.NET application. Only the config file of the running application (be it web or desktop) is loaded automatically.
Look up some articles on how config files work in the .NET environment to learn the basics of what is and isn't loaded, it'll definitely help you avoid headaches like this in the future.
Alternatively, if you know the name of your assembly's config file you can add a file attribute to your <AppSettings> element, pointing to that file if it's copied to the same directory as the web.config is in.
<appSettings file="privateassembly.config">
Please note that any appsetting with the same name declared in the web.config will be overridden by the privateassembly.config. Also note that any change to privateassembly.config (while the ASP.NET application is running) will not reset the application pool and thus will not be loaded into the AppDomain.
I have a C# application to load custom configuration section from assembly in different folder.
For example:
AppBase: C:\Code
Assembly Folder: C:\Lib\My.Core.dll
I have error says "System can't find specific file". I understand it is caused by different folder. Can I reference it in absolute path?
Here is my config file:
<section name="regional" type="My.Core.RegionalSection, My.Core" />
Can I make it something like
<section name="regional" type="My.Core.RegionalSection, C:\Lib\My.Core" />
No, you cannot specify a path in a type description. The CLR looks for assemblies in the GAC or the directory that contains the startup EXE. You can let it look in subdirectories by using the <probing> element in your .config file. Other paths that are completely unrelated to the startup EXE directory requires implementing the AppDomain.AssemblyResolve event.
Deploying DLLs in the same directory as the EXE is a wise thing to do. It avoids DLL Hell.
I have a class library which needs some configuration to function. This class library is referenced by multiple applications (Multiple ASP.Net websites, and Windows Forms applications)
It is my understanding that it is possible to store the configuration in the library's app.config => myDll.dll.config file. See: Putting configuration information in a DLL, and C# Dll config file
My issue is that I don't want to manually handle copying the config file to the bin folder of every host assembly. Is there a mechanism in .Net to handle pairing of the dll to its config file so that the accompanying configuration is copiled along with the dll whereever it is distributed/referenced?
If the config is the same for all instances of your dll, then I'd add it as an embedded resource, so it's part of your dll and not a separate file at all.
TO do this, either add it as a file resource to your Resources.resx file, or just add the file directly to your Project and then set its compile type (in the Properties window) to Embedded Resource.
You can then use Assembly.GetExecutingAssembly.GetManifestResourceNames() to list the names of the resources in your dll, and Assembly.GetExecutingAssembly.GetManifestResourceStream() to get a stream to read the file's data from. I'd probably use a simple homebrew XML format for my data and then an XmlTextReader/XmlDocument to read it very easily back in.
You'l have to deploy this .dll into GAC and put there the config file, all apps will first search the GAC when loanding a reference. Here is how you can deploy the dll + config.