Ejemplo n.º 1
0
        public static Object CreateDynamic(String assemblyName, String className, SqlDBCredentials credentials, bool checkDeclarations = false, SoftwareVersion version = null, Type defaultDSType = null, bool readOnly = false)
        {
            /** make a copy of these */
            credentials = credentials.Clone();

            /** ensure version is valid */
            if (version == null)
            {
                version = new SoftwareVersion();
            }

            InternalDatabaseType databaseType = InternalDatabaseType.Unknown;


            Object retVal = null;

            try
            {
                _instanceLock.Lock();
                SoftwareVersion initialVersion = version;
                Assembly        asm            = null;
                Type            t = null;
                try
                {
                    asm = Assembly.LoadFrom(assemblyName);
                    t   = asm.GetType(className);
                }
                catch (Exception e)
                {
                    throw new DataSourceException("DataSource Factory unable to load Datasource from Assembly: {0} - {1}", assemblyName, e);
                }

                _InstanceLookup.GetByType(t, credentials, version);

                // No cached instance of the proper datasource for these credentials about. Try and find one.
                if (retVal == null)
                {
                    // Now we get the database version from the lookup or database
                    if (version == SoftwareVersion.Empty && !(GetDatabaseVersion(credentials, out version, out databaseType).ResultCode == DBResult.Result.Success))
                    {
                        throw new DataSourceException("DataSource Factory unable to obtain version from Database: {0} (2)", credentials.Host);
                    }


                    //1. Get specified version of T. Routine will Start at T and look at descendants, caching results.
                    Type type = _TypeLookup.GetByType(t, version);

                    //1a. Throw exception if T has no version decorations
                    if (type == null)
                    {
                        if (defaultDSType == null)
                        {
                            throw new DataSourceException("Unable to find  version {0} of DataSource {1}", version, t);
                        }
                        else
                        {
                            type = defaultDSType;
                        }
                    }

                    bool saveDeclarationCheck = false;
                    /** save global declaration check flag */
                    if (type.IsSubclassOf(typeof(DataSourceBase)))
                    {
                        saveDeclarationCheck             = DataSourceBase.CheckDeclarations;
                        DataSourceBase.CheckDeclarations = checkDeclarations;
                    }

                    /** Create instance with proper parameters */
                    retVal = Activator.CreateInstance(type, credentials);
                    _InstanceLookup.SetByType(t, credentials, version, retVal);
                    if (initialVersion != version)
                    {
                        _InstanceLookup.SetByType(t, credentials, initialVersion, retVal);
                    }

                    /** restore global declaration check flag */
                    if (type.IsSubclassOf(typeof(DataSourceBase)))
                    {
                        DataSourceBase.CheckDeclarations = saveDeclarationCheck;
                    }

                    if (retVal is DataSourceBase)
                    {
                        ((DataSourceBase)(Object)retVal).ReadOnly     = readOnly;
                        ((DataSourceBase)(Object)retVal).DatabaseType = databaseType;
                    }
                }
            }
            catch (Exception e)
            {
                Log.SysLogText(LogLevel.ERROR, "DataSourceFactory Exception: {0}", e.Message);
                if (e.InnerException != null)
                {
                    Log.SysLogText(LogLevel.ERROR, "   Inner Exception: {0}", e.InnerException.Message);
                }

                /** rethrow */
                throw e;
            }
            finally
            {
                _instanceLock.Unlock();
            }
            return(retVal);
        }