I have a solution with multiple project using the same domain model. I thus created a class library that holds my domain models. This class library also contains other parameters that are used within my projects. I then add the reference to the class library in each of my projects.
My class library also has some repository classes derived from this example.
I however have an issue with connecting to a database. I want my class library to be able to connect to the database since I defined my database context class in there, where I set my database sets. With a single project, I usually define my connection string in my web.config file. But the class library has no web.config file. How do I set my connection string?
EDIT
Say i have the constructor of my database context, mydbcontext, defined in the class library as
public mydbcontext() : base(ConfigurationManager.ConnectionStrings["DatabaseCon"].ConnectionString)
{
}
If I understanding this right, will it be OK to just set the name of the connection string of each project to "DatabaseCon"?
You don't.
Pass in the connection string as a dependency to whatever classes that require it.
You can encapsulate the access to it - but you should instantiate it in whatever program that uses this library. This program will hold the connection string in its configuration.
You should define the connection string in the web.config file of the application that is using the class library. As an alternative you could hardcode the connection string into the constructor of your DbConext inside the class library - pretty bad approach because you won't be able to modify it from the outside - for example you will have hard time managing different connection strings for the different environments - staging, production, ...
Related
I am building an app that mostly provide REST services, nothing fancy. since my data consumed by the app can have multiple languages I thought about using the bundle files.
I created 3 files, one with the default file name and another two with specific languages. The files created using intellij IDE I am using.
I followed this guide https://www.baeldung.com/java-resourcebundle however on each run I am getting:
MissingResourceException: Can't find bundle for base name tp_app_strings, locale en_US
I tried numerous articles but none of them seems to resolve the issue.
One fun fact is that if I am using the #Value("classpath:tp_app_strings.properties") on a 'Resource' field I am able to get a reference to that file, so it spring is able to find it.
Additional thing that I tried was to create a WEB-INF directory and place the files there (read it in some article) but still no positive affect
The project structure is quite straight forward:
Spring boot version 2.2 running tomcat.
Any suggeestions would be highly appriciated
You can load the .properties file to the application context using #PropertySource annotation instead using #Value to load the .properties file to a org.springframework.core.io.Resource instance.
The usage;
#Configuration
#PropertySource("classpath:tp_app_strings.properties")
public class DefaultProperties {
#Value("${property1.name}") // Access properties in the above file here using SpringEL.
private String prop1;
#Value("${property2.name}")
private String prop2;
}
You wouldn't need java.util.ResourceBundle access properties this way. Use different or same class to load other .properties files as well.
Update 1:
In order to have the functionality of java.util.ResourceBundle, you can't just use org.springframework.core.io.Resource class. This class or non of it sub-classes don't provide functions to access properties by its name java.util.ResourceBundle whatsoever.
However, if you want a functionality like java.util.ResourceBundle, you could implement something custom like this using org.springframework.core.io.Resource;
#Configuration
public class PropertyConfig {
#Value("classpath:tp_app_strings.properties")
private Resource defaultProperties;
#Bean("default-lang")
public java.util.Properties getDefaultProperties() throws IOException {
Properties props = new Properties();
props.load(defaultProperties.getInputStream());
return props;
}
}
Make sure to follow correct naming convention when define the property file as java.util.Properties#load(InputStream) expect that.
Now you can #Autowire and use this java.util.Properties bean wherever you want just like with java.util.ResourceBundle using java.util.Properties#getProperty(String) or its overloaded counterpart.
I think it's problem of you properties file naming convention. use underline "_" for specifying locale of file like
filename_[languageCode]_[regionCode]
[languageCode] and [regionCode] are two letters standard code that [regionCode] section is optional
about code abbrivation standard take a look on this question
in your case change file name to tp_app_strings_en_US.properties
Is it possible to create a code-first Entity Framework model that connects to an existing database using ODP.Net without having any settings in the app.config file?
I have tried many different things.
Currently I am setting DbConfiguration:
sealed class EntityFrameworkConfiguration : DbConfiguration
{
public static readonly DbConfiguration Instance = new EntityFrameworkConfiguration();
EntityFrameworkConfiguration()
{
this.SetDefaultConnectionFactory(new OracleConnectionFactory());
this.SetProviderServices("Oracle.ManagedDataAccess.Client", EFOracleProviderServices.Instance);
}
}
DbConfiguration.SetConfiguration(EntityFrameworkConfiguration.Instance);
I am passing an OracleConnection directly into the EF context.
However, I either have problems with the SQL being generated in SQL Server format (using double-quotes around table aliases), or I get the following error:
An unhandled exception of type 'System.NotSupportedException' occurred in EntityFramework.dll
Additional information: Unable to determine the provider name for provider factory of type 'Oracle.ManagedDataAccess.Client.OracleClientFactory'. Make sure that the ADO.NET provider is installed or registered in the application config.
Has anyone any experience of getting this to work without polluting app.config with crud?
Yes. To complete the switch from machine.config/app.config to code-based configuration, I had to also include a call to SetProviderFactory().
public sealed class EntityFrameworkConfiguration : DbConfiguration
{
public static readonly DbConfiguration Instance = new EntityFrameworkConfiguration();
public EntityFrameworkConfiguration()
{
SetDefaultConnectionFactory(new OracleConnectionFactory());
SetProviderServices("Oracle.ManagedDataAccess.Client", EFOracleProviderServices.Instance);
SetProviderFactory("Oracle.ManagedDataAccess.Client", new OracleClientFactory());
}
}
I also called DbConfiguration.SetConfiguration(EntityFrameworkConfiguration.Instance); in the startup of my application because I had DbContext's in multiple assemblies that all needed to share this configuration.
On a side note, I have also found this to be effective in allowing your application to work around the ConfigurationErrorsException: The 'DbProviderFactories' section can only appear once per config file for cases where you may not have access to repair the user's machine.config.
Uff. Found the problem.
Because I was registering column mapping using lower case the query didn't work. The column and table names must be in upper-case.
How silly.
So, I am creating a class library that handles user information like username, password, etc. I want to do this so that I can just reference this library with any of my web apps and not have to continuously rewrite the user information part.
In, the user information class library, I want to handle the login. I've done this before in app_code that was a part of the web project by using HttpContext.Current.Session. But, when I try to use it in my class library (even while using System.Web) it throws a compile error saying that HttpContext does not exist in this context. How can I get access to it?
When creating a utility type class that works with a dependency like HttpContext, your best bet is to pass the context or the session into the class either via a constructor or the method call. That way, it is explicit to the consumers of your class that it requires this object to function. This also allows you to test your class in isolation.
Even better, if you are working with a few specific properties that have basic types then you can accept those properties as inputs. That way, you are not creating any dependencies on a UI framework for your utility library.
I am setting up a dev, qa, staging, production system of deployment. I would like to be able to promote a release from one environment to the next without having to re-publish from VS, and without manually touching any files.
I need separate databases for DEV, QA and STG/PRO , so this would mean connection strings need to be switched dynamically according to the environment.
I could do this in a data layer -- perhaps something similar to this: Managing ASP.NET Development, Staging and Production Connection Strings (without pulling your hair out) -- but my data layer is built upon Entity Framework.
QUESTION: Is there a way to achieve dynamic switching of connection strings while using Entity Framework?
I am setting up a dev, qa, staging, production system of deployment. I
would like to be able to promote a release from one environment to the
next without having to re-publish from VS, and without manually
touching any files.
This is really strange and bad requirement. It is absolutely common to reconfigure application during deployment to different environment. Instead of hardcoding this in your application you should have different set of installation / deployment scripts which would also change your configuration file when moving from one environment to another.
Holding configuration for all environments in the configuration is IMHO very bad practice.
Even with hardcoded solution you still need to change some "configuration" to tell application which environment it currently runs on. Hardcoded solution will use information about environment to select correct connections string from configuration file and pass it to context constructor.
As example of the mentioned approach you can try this. It will still require you to change environment variable each time you redeploy application - complexity of such modification in custom deployment script is exactly the same as replacing connection string:
Configuration file:
<appSettings>
<add key="environment" value="Dev"/>
</appSettings>
<connectionStrings>
<add name="Dev" connectionString="..."/>
</connectionStrings>
Code for context factory method:
public static YourContext ContextFactory()
{
string environment = WebConfigurationManager.AppSettings["environment"].Value;
// This should be correctly recognized as a name of connection string.
return new YourContext(environment);
}
Context:
public class YourContext : DbContext
{
public YourContext(string connectionStringName) : base(connectionStringName)
{ }
}
Assuming that you are using a unit of work pattern; it means that your object context is recreated after every unit of work.
You likely have a class, that inherits from some sort of object context so in the constructor you use to create that context you can reference the base constructor that allows you to pass in a connection string.
From there, you can call a static method or new up an object to handle the creation of a connection string or pass in an entity connection.
If you are using a DbContext, it is the same, only with DbConnection instead of EntityConnection.
In my web application project I am using MYSQLMemberShipProvider. Now I want that instead of reading the connection string from web.config file, it will read the connection string from external file every time.
So that I am implementing the custom membership provider class, this class inherits the MembershipProvider class.
But the problem is that if I inherits the MembershipProvider class then I have to implement all of its method in my custom membership provider class, But I want to use all other inbuilt methods of Memebership. What can I do.
I only want to add the code like below:
public class CustomSqlMembershipProvider :MembershipProvider
{
public override void Initialize(string name, NameValueCollection configs)
{
base.Initialize(name, configs);
Connectionstring objProducts = // reading the connection string.
}
}
But on compilation it is giving me the error does not implement inherit abstract member.
Please Suggest me any idea.
Thanks in advance
Aayushi
What are your motivations for reading in the connection string from another file, is it purely to get a different connection string for debug/release environments? If that is the case you could use web.config transformations if you have VS2010. It is a very clean solution that may be of use to you.