public void TestRepository() { // Create a description manually and add it to the repository. var manualDescription = new DbProviderFactoryDescription { Description = ".NET Framework Data Provider for SuperDuperDatabase", InvariantName = "SuperDuperDatabase", Name = "SuperDuperDatabase Data Provider", AssemblyQualifiedName = "SuperDuperDatabase.SuperDuperProviderFactory, SuperDuperDatabase", }; // Initialize the repository. var repo = new DbProviderFactoryRepository(); repo.Add(manualDescription); var descs = repo.GetAllDescriptions(); foreach (var description in descs) { //get the description individually var desc = repo.GetDescriptionByInvariant(description.InvariantName); Assert.AreEqual(description.AssemblyQualifiedName, desc.AssemblyQualifiedName); //get a factory var factory = repo.GetFactory(desc); //may be null if not accessible } //look in the current directory repo.LoadExternalDbProviderAssemblies(Environment.CurrentDirectory); }
/// <summary> ///Gets the factory. /// </summary> /// <param name="description">The description.</param> /// <returns></returns> public DbProviderFactory GetFactory(DbProviderFactoryDescription description) { var providerType = //AssemblyHelper.LoadTypeFrom(description.AssemblyQualifiedName); Type.GetType(description.AssemblyQualifiedName); if (providerType == null) return null; var providerInstance = providerType.GetField("Instance", BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Static); if (providerInstance == null) return null; if (!providerInstance.FieldType.IsSubclassOf(typeof(DbProviderFactory))) return null; try { var factory = providerInstance.GetValue(null); return factory != null ? (DbProviderFactory)factory : null; } catch (TargetInvocationException) { return null; } }
public void FactoryToolsTest() { const string providername = "System.Data.SqlClient"; //this is normally used var provider = FactoryTools.GetFactory(providername); Assert.AreEqual("System.Data.SqlClient.SqlClientFactory", provider.GetType().FullName, "No override, returns SqlClient"); //override with a repository FactoryTools.ProviderRepository = new DbProviderFactoryRepository(); var manualDescription = new DbProviderFactoryDescription { Description = ".NET Framework Data Provider for SuperDuperDatabase", InvariantName = "SuperDuperDatabase", Name = "SuperDuperDatabase Data Provider", AssemblyQualifiedName = typeof(SuperDuperProviderFactory).AssemblyQualifiedName, }; FactoryTools.ProviderRepository.Add(manualDescription); provider = FactoryTools.GetFactory(providername); Assert.AreEqual("System.Data.SqlClient.SqlClientFactory", provider.GetType().FullName, "Overridden, but returns underlying SqlClient"); provider = FactoryTools.GetFactory("SuperDuperDatabase"); Assert.AreEqual(typeof(SuperDuperProviderFactory), provider.GetType(), "Overridden, returns manually added provider"); //override with a single provider FactoryTools.SingleProviderFactory = SqlClientFactory.Instance; provider = FactoryTools.GetFactory("Xxxx"); Assert.AreEqual("System.Data.SqlClient.SqlClientFactory", provider.GetType().FullName, "Overridden, always returns SqlClient"); ProviderChecker.Check(providername, ConnectionStrings.Northwind); var dr = new DatabaseReader(ConnectionStrings.Northwind, "Xxxxx", 0); var tables = dr.TableList(); Assert.IsTrue(tables.Count > 0, "We called the reader with a bogus provider type, but we got the overridden type"); }
public void FactoryToolsTest() { const string providername = "System.Data.SqlClient"; //this is normally used var provider = FactoryTools.GetFactory(providername); Assert.AreEqual("System.Data.SqlClient.SqlClientFactory", provider.GetType().FullName, "No override, returns SqlClient"); //override with a repository FactoryTools.ProviderRepository = new DbProviderFactoryRepository(); var manualDescription = new DbProviderFactoryDescription { Description = ".NET Framework Data Provider for SuperDuperDatabase", InvariantName = "SuperDuperDatabase", Name = "SuperDuperDatabase Data Provider", AssemblyQualifiedName = typeof(SuperDuperProviderFactory).AssemblyQualifiedName, }; FactoryTools.ProviderRepository.Add(manualDescription); provider = FactoryTools.GetFactory(providername); Assert.AreEqual("System.Data.SqlClient.SqlClientFactory", provider.GetType().FullName, "Overridden, but returns underlying SqlClient"); provider = FactoryTools.GetFactory("SuperDuperDatabase"); Assert.AreEqual(typeof(SuperDuperProviderFactory), provider.GetType(), "Overridden, returns manually added provider"); //override with a single provider FactoryTools.SingleProviderFactory = SqlClientFactory.Instance; provider = FactoryTools.GetFactory("Xxxx"); Assert.AreEqual("System.Data.SqlClient.SqlClientFactory", provider.GetType().FullName, "Overridden, always returns SqlClient"); ProviderChecker.Check(providername, ConnectionStrings.Northwind); var dr = new DatabaseReader(ConnectionStrings.Northwind, "Xxxxx"); var tables = dr.TableList(); Assert.IsTrue(tables.Count > 0, "We called the reader with a bogus provider type, but we got the overridden type"); }
/// <summary> ///Adds the specified provider. /// </summary> /// <param name="provider">The provider.</param> public void Add(DbProviderFactoryDescription provider) { Delete(provider); _dbProviderFactoryTable.Rows.Add(provider.Name, provider.Description, provider.InvariantName, provider.AssemblyQualifiedName); }
/// <summary> ///Deletes the specified provider if present. /// </summary> /// <param name="provider">The provider.</param> private void Delete(DbProviderFactoryDescription provider) { var row = _dbProviderFactoryTable.Rows.Cast<DataRow>() .FirstOrDefault(o => o["InvariantName"] != null && o["InvariantName"].ToString() == provider.InvariantName); if (row != null) { _dbProviderFactoryTable.Rows.Remove(row); } }
/// <summary> ///Loads the external database provider assemblies. /// </summary> /// <param name="path">The path.</param> /// <param name="includeSubfolders">if set to <c>true</c> [include subfolders].</param> /// <exception cref="System.ArgumentNullException"></exception> /// <exception cref="System.ArgumentException">$Path does not {path} exist.</exception> public void LoadExternalDbProviderAssemblies(string path, bool includeSubfolders) { if (string.IsNullOrEmpty(path)) { throw new ArgumentNullException("path"); } if (!Directory.Exists(path)) { throw new ArgumentException(String.Format("Path {0} does not exist.", path), "path"); } // main directory var mainDirectory = new DirectoryInfo(path); var directories = new List<DirectoryInfo> { mainDirectory }; // also search in direct subfolders if (includeSubfolders) { directories.AddRange(mainDirectory.GetDirectories()); } // iterate over all directories and search for dll libraries foreach (var directory in directories) { foreach (var file in directory.GetFiles().Where(file => String.Equals(file.Extension, ".dll", StringComparison.OrdinalIgnoreCase))) { // This will work to load only the file from other directory without dependencies! But at access time the dependecies are necessary! //var assembly = Assembly.LoadFile(file.FullName); // Load all assemblies from directory in current AppDomain. This is necessary for accessing all types. Other // opertunities like Assembly.LoadFile will only load one file temporary (later access will not have dependecy finding) // and Assembly.ReflectionOnlyLoad will load all dependencies at beginning what will not work in other directories as bin. AssemblyName assemblyName; try { assemblyName = AssemblyName.GetAssemblyName(file.FullName); } catch (BadImageFormatException) { //dll isn't .net (eg SQLite.Interop.dll) continue; } var assembly = AppDomain.CurrentDomain.Load(assemblyName); foreach (var type in assembly.GetLoadableTypes()) { if (type.IsClass) { if (typeof(DbProviderFactory).IsAssignableFrom(type)) { // Ignore already existing provider if (GetDescriptionByInvariant(type.Namespace) == null) { var newDescription = new DbProviderFactoryDescription { Description = ".Net Framework Data Provider for " + type.Name, InvariantName = type.Namespace, Name = type.Name + " Data Provider", AssemblyQualifiedName = type.AssemblyQualifiedName }; Add(newDescription); } } } } } } }