C# Access app.config file in 3 layers architecture - winforms

I'm making a small project using 3 layers architecture. I have read a topic in Microsoft forum that App.config file can only be access in GUI layer. My DAL(Data Access Layer) layer is class library project so I can't create App.config to store connection string. It's not true if I reference GUI project to DAL to access App.config file. So I have created a text file to store my connection string. But It's not safe.
Is there anyway to access App.config to get connection string?
Thanks!

Related

How to remove EntityFramework.SqlServer Reference from WebApplication project in a DDD Solution

I have a highly standardized project in DDD (Domain-Driven Design), so it means that each layer has it's responsibilities and no layer knows other than itself and the Domain Layer.
Here's the structure of my project:
My Infra.Data layer is responsible for connecting with the Database, and i'm persisting using EntityFramework.
My problem is: in order to make it work with SQLServer Databases, i need to add a reference to EntityFramework.SqlServer in my WebApplication layer, which breaks my separation of concerns concept, as you can see below.
Even having the same reference in my Infra.Data layer, which is where it only should be, as you can see below.
If i remove the EntityFramework.SqlServer reference from the WebApplication layer, it stops working, and throws exception every time i try to persist data, as you can see below.
I need to know how to remove this reference to keep separation of concerns, because the way it is now, i'll have to change my WebApplication if i want to change my persistence. My Web layer is prohibited to even have anything with the word "EntityFramework" in it. I want FULL separation of concerns to change any layer without affecting no other.
If i register my <entityFramework> provider in my Web.config file, it will only works if i have the EntityFramework.SqlServer in the project, but without the EntityFramework.SqlServer reference on the WebApplication, it miss namespaces and complain about it.
Note: My project also connects to MySql Databases successfully, and i don't need no references to MySql.Data or any other MySql library in my WebApplication layer, as expected.
Please help me, my DDD/Separation of Concerns OCD is cracking on it, thanks.
You can!
Just create this class in your Infra.Data project:
internal static class ForceEFToCopyDllToOutput
{
private static SqlProviderServices instance = SqlProviderServices.Instance;
}
When you do this you let the compiler know that the specific resource is used and should be available in the bin folder.
Some consider this a hack but it's useful if you want to keep your layers free from infrastructure concerns.
You can read more about this here: DLL reference not copying into project bin
EDIT:
All you'll need now is to copy the connection string from your Infra.Data app.config to your WebApplication web.config
<connectionStrings>
<add name="DatabaseConnectionString" providerName="System.Data.SqlClient" connectionString="..." />
</connectionStrings>
You would not be able to get rid of Entity-framework configuration and the required DLL in your Web-application :
Lets say your infrastructure layer and domain layer need to depend on Entity-framework. This means these two libraries need to have physical access to Entity Framework DLLs(Have Entity-framework package installed) and configured.
When you run your web application which has dependency on infrastructure and domain libraries, all Dlls used by underlying libraries (infrastructure and domain) need to be present physically and configured otherwise you will have run time issue(program might be compile-able but you will get run-time errors).
Morale of the story : If application x [Irrespective of the layer it belongs to] has dependency to library y,z and library y,z rely on some dll and require configuration, for application x to work at run-time you need to have all dlls needed by y,z available and provide their configuration (web.config) in your instance.
You can obviously provide some workarounds such as copying the files directly and providing separate config files for each layer but I strongly advise against it because it would get extremely messy and very hard to maintain in the long run.

Multiple winforms projects - need to alter app.config files at time of install

I have a winforms solution with multiple projects (UI, web services, data access). All of these projects have their own app.config file. At install time, I need to change the connection string in the data access project based on user's database configuration.
But the data access project creates a dll at install time, with no app.config file available for updating. The UI project is the only project with an app.config file created. And the UI project has a reference to the data access project, so I don't believe the data access project can "see" the config settings of the UI project.
I have searched SO for an answer but have not found anything specific to this situation. Am I doing something wrong in how my projects are set up? Any help would be appreciated.
For anyone else facing this issue:
I believe I found the answer here
In Visual Studio, on the properties of each config file, you can choose "Copy Always" for Copy to Output Directory. This will explicitly create the config file for dll projects.
Then in InstallShield, you can refer to this config file ("MyApplication.dll.config" for example), and alter the connection string through the "Text File Changes" section under "System Configuration". When the user is prompted to connect to a sql server, InstallShield can use those connection properties to alter the connection string in the config file.

Machine config instead of app.config files for console apps

Is it possible to use connection strings in a Console app's app.config file in a single machine config file instead? So all console apps on the server can use the same file?
You could, but that would mean that any .NET application could gain access to your database.
I would advise against it, for several reaons:
A possible security hole.
Most developers would look for this information in app.config not machine.config.
You may end up sharing connection strings that only one or two applications need with all applications.
You can't limit what applications will be able to use the connection strings.
You will not be able to simply move the application to another machine, with the app.config file and have everything just work (you will also need to import the connection string information to the new machine.config).
You really should keep the configuration with the application that uses it.

Scala/Lift Database Connections

I am working on a new web application using Scala with Lift. I want to make it reusable so others might install it on their own servers for their own needs. I come out of a PHP background where it is common practice to create an install form asking for database connection details. This information is stored in a configuration file and used by the rest of the PHP application for connecting to the database. It is extremely convenient for the user because everything is contained within the directory storing the PHP files. They are free to define everything else. My Java/Scala background has all been enterprise work where an application was only intended to run on the database we setup for it. It was not meant to be installed on others' web servers or with different databases.
So my question is how is this typically done for the Java/Scala world? If there are open source applications implementing the mainstream solution, feel free to point me to those too.
I use this to set up the database:
val vendor =
new StandardDBVendor(
Props.get("db.driver") openOr "org.h2.Driver",
Props.get("db.url") openOr "jdbc:h2:mem:db;AUTO_SERVER=TRUE",
Props.get("db.user"),
Props.get("db.password"))
LiftRules.unloadHooks.append(vendor.closeAllConnections_! _)
DB.defineConnectionManager(DefaultConnectionIdentifier, vendor)
The 'Props' referred to will then be (by default) in the file default.props in the props directory in resources.
Updated: This is what I do on servers in production. With 'Props.whereToLook' you provide a function that retrieves an input stream of the configuration. This can be a file as in the example below or you could for example fetch it over network socket.
You will probably let the application to fail with an error dialog.
val localFile = () => {
val file = new File("/opt/jb/myapp/etc/myapp.props")
if (file.exists) Full(new FileInputStream(file)) else Empty
}
Props.whereToLook = () => (("local", localFile) :: Nil)
I am not sure if I am missing your points.
By default, Lift use Scala source file(Boot.scala) to configure all the settings, because Lift doesn't wanna introduce other language into the framework, however you can override some of the configurations using a .properties file.
In Java/Scala world, we use .properties file. It's just a plain text file used for configuration or localization etc,just like text configuration files in PHP.
Lift Framework has it's default support for the external database configuration files, you check out the code in Boot.scala, that's if a .properties file existed, the database will initialized using the connection configuration, if it doesn't, it will use the source file configuration.

How do I load a module catalog from a database in Prism?

I'm using Prism in my WPF application and up to now, I've been loading the modules via var moduleCatalog = new ConfigurationModuleCatalog();. I'd like to get the module catalog from a database. The Prism documentation indicates that this is possible, but it doesn't go into any details.
Has anyone done this and can provide some guidance?
This is a theoretical possibility, but it's not in any samples I've seen.
Basically what you'd do is either base64 encode the DLLs / Files into the database or zip them up and store them in one blob. You'd download them in your bootstrapper and copy them locally (in a temp directory) and then allows them to load normally from the filesystem using the DirectoryModuleCatalog. If you wanted it to be a bit more elegant, you could write your own ModuleCatalog that encapsulates this logic.
This is very similar to what I do... I actually download a zip file of all of the modules from a website at launch time and unzip them and load them with the DirectoryModuleCatalog.
You can write your own ModuleCatalog implementation by implementing IModuleCatalog. Your implementation can then populate the catalog by any means you define.
You could also use the CreateFromXAML overload that accepts a Stream and implement a webservice that delivers the ModuleCatalog in XAML over HTTP.

Resources