PetaPoco icon indicating copy to clipboard operation
PetaPoco copied to clipboard

T4 template GetConnectionString to return connection string from another project

Open darko1979 opened this issue 8 years ago • 0 comments

I have a solution with multiple projects: MainApp, Common and Service (Common is a library shared by MainApp and Service). ConnectionString is located in web.config in Service project. I wanted to have PetaPoco models in Common library project but current T4 template cannot read config's from another projects so I created alternative GetConnectionString2 that searches through all config's in all projects:

string GetConnectionString2(ref string connectionStringName, out string providerName)
{
    var configPaths = new List<string>();

    IServiceProvider _ServiceProvider = (IServiceProvider)Host;
    if (_ServiceProvider == null)
        throw new Exception("Host property returned unexpected value (null)");
	
    EnvDTE.DTE dte = (EnvDTE.DTE)_ServiceProvider.GetService(typeof(EnvDTE.DTE));
    if (dte == null)
        throw new Exception("Unable to retrieve EnvDTE.DTE");

	foreach (EnvDTE.Project project in dte.Solution.Projects)
	{
		foreach (EnvDTE.ProjectItem item in project.ProjectItems)
		{
			// if it is the app.config file, then open it up
			if (item.Name.Equals("App.config",StringComparison.InvariantCultureIgnoreCase) || item.Name.Equals("Web.config",StringComparison.InvariantCultureIgnoreCase))
			{
			    System.IO.FileInfo info = new System.IO.FileInfo(project.FullName);
				configPaths.Add(System.IO.Path.Combine(info.Directory.FullName, item.Name));
			}
	    }
	}

    if (configPaths.Count == 0)
        throw new ArgumentNullException("The project does not contain App.config or Web.config file.");

    providerName=null;    
    string result="";

	foreach (string configPath in configPaths)
	{
		ExeConfigurationFileMap configFile = new ExeConfigurationFileMap();
		configFile.ExeConfigFilename = configPath;       
		var config = System.Configuration.ConfigurationManager.OpenMappedExeConfiguration(configFile, ConfigurationUserLevel.None);
		var connSection = config.ConnectionStrings;

		//if the connectionString is empty - which is the defauls
		//look for count-1 - this is the last connection string
		//and takes into account AppServices and LocalSqlServer
		if(string.IsNullOrEmpty(connectionStringName))
		{
	        if(connSection.ConnectionStrings.Count>1)
			{
				connectionStringName = connSection.ConnectionStrings[connSection.ConnectionStrings.Count-1].Name;
				result=connSection.ConnectionStrings[connSection.ConnectionStrings.Count-1].ConnectionString;
				providerName=connSection.ConnectionStrings[connSection.ConnectionStrings.Count-1].ProviderName;
				break;
			}
		}
		else
		{
			var cs = connSection.ConnectionStrings[connectionStringName];
			if (cs != null)
			{
				result = cs.ConnectionString;
				providerName = cs.ProviderName;
				break;
			}
		}
	}

	if(!string.IsNullOrEmpty(connectionStringName) && string.IsNullOrEmpty(result))
	{
            result="There is no connection string name called '"+connectionStringName+"'";
	}

    return result;
}

darko1979 avatar Nov 25 '16 06:11 darko1979