示例#1
0
        /// <summary>
        /// Gets the Spring IDbProvider given the ISessionFactory.
        /// </summary>
        /// <remarks>The matching is performed by comparing the assembly qualified
        /// name string of the hibernate Driver.ConnectionType to those in
        /// the DbProviderFactory definitions.  No connections are created
        /// in performing this comparison.</remarks>
        /// <param name="sessionFactory">The session factory.</param>
        /// <returns>The corresponding IDbProvider, null if no mapping was found.</returns>
        /// <exception cref="InvalidOperationException">If DbProviderFactory's ApplicaitonContext is not
        /// an instance of IConfigurableApplicaitonContext.</exception>
        public static IDbProvider GetDbProvider(ISessionFactory sessionFactory)
        {
            ISessionFactoryImplementor sfi = sessionFactory as ISessionFactoryImplementor;

            if (sfi != null)
            {
                IConnectionProvider cp = sfi.ConnectionProvider as IConnectionProvider;
                if (cp != null)
                {
                    IConfigurableApplicationContext ctx =
                        Spring.Data.Common.DbProviderFactory.ApplicationContext as IConfigurableApplicationContext;
                    if (ctx == null)
                    {
                        throw new InvalidOperationException(
                                  "Implementations of IApplicationContext must also implement IConfigurableApplicationContext");
                    }

#if NET_1_1
                    DriverBase db = cp.Driver as DriverBase;
#else
                    IDriver db = cp.Driver;
#endif
                    if (db != null)
                    {
                        Type hibCommandType = db.CreateCommand().GetType();

                        string[] providerNames = ctx.GetObjectNamesForType(typeof(DbProvider), true, false);
                        string   hibCommandAQN = hibCommandType.AssemblyQualifiedName;
                        foreach (string providerName in providerNames)
                        {
                            IObjectDefinition                     objectdef    = ctx.ObjectFactory.GetObjectDefinition(providerName);
                            ConstructorArgumentValues             ctorArgs     = objectdef.ConstructorArgumentValues;
                            ConstructorArgumentValues.ValueHolder vh           = ctorArgs.NamedArgumentValues["dbmetadata"] as ConstructorArgumentValues.ValueHolder;
                            IObjectDefinition                     od           = ((ObjectDefinitionHolder)vh.Value).ObjectDefinition;
                            ConstructorArgumentValues             dbmdCtorArgs = od.ConstructorArgumentValues;
                            string commandType = dbmdCtorArgs.GetArgumentValue("commandType", typeof(string)).Value as string;

                            if (hibCommandAQN.Equals(commandType))
                            {
                                IDbProvider prov = Spring.Data.Common.DbProviderFactory.GetDbProvider(providerName);
                                return(prov);
                            }
                        }
                    }
                    else
                    {
                        log.Info("Could not derive IDbProvider from SessionFactory");
                    }
                }
            }
            return(null);
        }
示例#2
0
        public void SetsUpMongoDbFactoryUsingAMongoConnectStringWithoutCredentials()
        {
            string xml     = @"<?xml version='1.0' encoding='UTF-8' ?>
                           <objects xmlns='http://www.springframework.net' xmlns:mongo='http://www.springframework.net/mongo'>  
                             <mongo:db-factory url='mongodb://localhost/database' />
                           </objects>";
            var    factory = new XmlObjectFactory(new StringResource(xml, Encoding.UTF8));

            IObjectDefinition         definition           = factory.GetObjectDefinition("MongoDatabaseFactory");
            ConstructorArgumentValues constructorArguments = definition.ConstructorArgumentValues;

            Assert.That(constructorArguments.ArgumentCount, Is.EqualTo(1));

            var argument = constructorArguments.GetArgumentValue(0, typeof(MongoUrl));

            Assert.That(argument, Is.Not.Null);

            var dbFactory = factory.GetObject <IMongoDatabaseFactory>("MongoDatabaseFactory");
            var db        = dbFactory.GetDatabase();

            Assert.That(db.Name, Is.EqualTo("database"));
        }
        /// <summary>
        /// Create an array of arguments to invoke a constructor or static factory method,
        /// given the resolved constructor arguments values.
        /// </summary>
        /// <remarks>When return value is null the out parameter UnsatisfiedDependencyExceptionData will contain
        /// information for use in throwing a UnsatisfiedDependencyException by the caller.  This avoids using
        /// exceptions for flow control as in the original implementation.</remarks>
        private ArgumentsHolder CreateArgumentArray(string objectName, RootObjectDefinition rod, ConstructorArgumentValues resolvedValues, ObjectWrapper wrapper, Type[] paramTypes, MethodBase methodOrCtorInfo, bool autowiring, out UnsatisfiedDependencyExceptionData unsatisfiedDependencyExceptionData)
        {
            string methodType = (methodOrCtorInfo is ConstructorInfo) ? "constructor" : "factory method";

            unsatisfiedDependencyExceptionData = null;

            ArgumentsHolder args                 = new ArgumentsHolder(paramTypes.Length);
            ISet            usedValueHolders     = new HybridSet();
            IList           autowiredObjectNames = new LinkedList();
            bool            resolveNecessary     = false;

            ParameterInfo[] argTypes = methodOrCtorInfo.GetParameters();

            for (int paramIndex = 0; paramIndex < paramTypes.Length; paramIndex++)
            {
                Type paramType = paramTypes[paramIndex];

                string parameterName = argTypes[paramIndex].Name;
                // If we couldn't find a direct match and are not supposed to autowire,
                // let's try the next generic, untyped argument value as fallback:
                // it could match after type conversion (for example, String -> int).
                ConstructorArgumentValues.ValueHolder valueHolder = null;
                if (resolvedValues.GetNamedArgumentValue(parameterName) != null)
                {
                    valueHolder = resolvedValues.GetArgumentValue(parameterName, paramType, usedValueHolders);
                }
                else
                {
                    valueHolder = resolvedValues.GetArgumentValue(paramIndex, paramType, usedValueHolders);
                }


                if (valueHolder == null && !autowiring)
                {
                    valueHolder = resolvedValues.GetGenericArgumentValue(null, usedValueHolders);
                }
                if (valueHolder != null)
                {
                    // We found a potential match - let's give it a try.
                    // Do not consider the same value definition multiple times!
                    usedValueHolders.Add(valueHolder);
                    args.rawArguments[paramIndex] = valueHolder.Value;
                    try
                    {
                        object originalValue  = valueHolder.Value;
                        object convertedValue = TypeConversionUtils.ConvertValueIfNecessary(paramType, originalValue, null);
                        args.arguments[paramIndex] = convertedValue;

                        //?
                        args.preparedArguments[paramIndex] = convertedValue;
                    }
                    catch (TypeMismatchException ex)
                    {
                        //To avoid using exceptions for flow control, this is not a cost in Java as stack trace is lazily created.
                        string errorMessage = String.Format(CultureInfo.InvariantCulture,
                                                            "Could not convert {0} argument value [{1}] to required type [{2}] : {3}",
                                                            methodType, valueHolder.Value,
                                                            paramType, ex.Message);
                        unsatisfiedDependencyExceptionData = new UnsatisfiedDependencyExceptionData(paramIndex, paramType, errorMessage);
                        return(null);
                    }
                }
                else
                {
                    // No explicit match found: we're either supposed to autowire or
                    // have to fail creating an argument array for the given constructor.
                    if (!autowiring)
                    {
                        string errorMessage = String.Format(CultureInfo.InvariantCulture,
                                                            "Ambiguous {0} argument types - " +
                                                            "Did you specify the correct object references as {0} arguments?",
                                                            methodType);
                        unsatisfiedDependencyExceptionData = new UnsatisfiedDependencyExceptionData(paramIndex, paramType, errorMessage);

                        return(null);
                    }
                    try
                    {
                        MethodParameter param             = MethodParameter.ForMethodOrConstructor(methodOrCtorInfo, paramIndex);
                        object          autowiredArgument = ResolveAutoWiredArgument(param, objectName, autowiredObjectNames);
                        args.rawArguments[paramIndex]      = autowiredArgument;
                        args.arguments[paramIndex]         = autowiredArgument;
                        args.preparedArguments[paramIndex] = new AutowiredArgumentMarker();
                        resolveNecessary = true;
                    }
                    catch (ObjectsException ex)
                    {
                        unsatisfiedDependencyExceptionData = new UnsatisfiedDependencyExceptionData(paramIndex, paramType, ex.Message);

                        return(null);
                    }
                }
            }
            foreach (string autowiredObjectName in autowiredObjectNames)
            {
                if (log.IsDebugEnabled)
                {
                    log.Debug("Autowiring by type from object name '" + objectName +
                              "' via " + methodType + " to object named '" + autowiredObjectName + "'");
                }
            }


            return(args);
        }