Пример #1
0
        public static T Create <T>(SqlDBCredentials credentials, bool checkVersion = false, bool checkDeclarations = false, SoftwareVersion version = null, Type defaultDSType = null, bool readOnly = false)
        {
            /** make a copy of these */
            credentials = credentials.Clone();
            InternalDatabaseType databaseType = InternalDatabaseType.Unknown;

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

            T retVal = default(T);

            try
            {
                _instanceLock.Lock();

                SoftwareVersion initialVersion = version;
                _InstanceLookup.Get <T>(credentials, version);

                // No cached instance of the proper datasource for these credentials about. Try and find one.
                if (retVal == null)
                {
                    if (checkVersion == false)
                    {
                        version      = new SoftwareVersion("9.9");
                        databaseType = InternalDatabaseType.Unknown;
                    }
                    else
                    {
                        // 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} (1)", credentials.Host);
                        }
                    }

                    //1. Get specified version of T. Routine will Start at T and look at descendants, caching results.
                    Type type = _TypeLookup.Get <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, typeof(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 = (T)Activator.CreateInstance(type, credentials);
                    _InstanceLookup.Set <T>(credentials, version, retVal);
                    if (initialVersion != version)
                    {
                        _InstanceLookup.Set <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).Version      = version;
                        ((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);
        }