예제 #1
0
        /// <summary>
        /// Resolves the last registered service with a matching name.
        /// </summary>
        /// <typeparam name="TInterface"></typeparam>
        /// <param name="name"></param>
        /// <returns></returns>
        public TInterface Resolve <TInterface>(string name)
        {
            var interfaceType = typeof(TInterface);
            var typeAndName   = new TypeAndName(interfaceType, name);

            Type type;

            if (RegisteredTypes.TryGetValue(typeAndName, out type))
            {
                object lazyInstance;
                if (StoredServices.TryGetValue(typeAndName, out lazyInstance) && lazyInstance.GetType() == typeof(Func <TInterface>))
                {
                    // Lazy singletons must be invoked when called first time.
                    var invokedLazy = ((Func <TInterface>)lazyInstance).Invoke();
                    StoredServices.AddOrUpdate(typeAndName, k => invokedLazy, (k, v) => invokedLazy);
                }

                object instance;
                if (StoredServices.TryGetValue(typeAndName, out instance))
                {
                    // Return the stored singleton object.
                    return((TInterface)instance);
                }

                // Get the first constructor from the registered type.
                var constructor = type.GetConstructors().First();

                // Create a new instance and return it.
                var activator = Common.Activator.GetActivator(constructor);
                return((TInterface)activator());
            }

            return(default(TInterface));
        }
        private object InternalResolve(Type targetType)
        {
            if (targetType.IsClass)
            {
                ITypeDefinition typeDefinition;
                if (RegisteredTypes.TryGetValue(targetType, out typeDefinition))
                {
                    if (typeDefinition.SingletonInstance != null)
                    {
                        return(typeDefinition.SingletonInstance);
                    }

                    if (typeDefinition.ConstructorMethods == null || typeDefinition.ConstructorMethods.Length == 0)
                    {
                        throw new Exception(string.Format("constructor method cannot be found in type '{0}'", targetType.FullName));
                    }

                    var defaultConstructor = typeDefinition.ConstructorMethods[0];

                    var parameterValues = new object[defaultConstructor.ParameterInfos.Length];
                    for (int i = 0; i < parameterValues.Length; i++)
                    {
                        var parameterInfo = defaultConstructor.ParameterInfos.FirstOrDefault(x => x.Index == i);
                        if (parameterInfo == null)
                        {
                            throw new Exception(string.Format("parameter is missing in contructor method."));
                        }

                        parameterValues[i] = InternalResolve(parameterInfo.TypeDefinition.Info as Type);
                    }

                    return(typeDefinition.GetInstance(parameterValues));
                }

                return(null);
            }
            else if (targetType.IsInterface)
            {
                var typeDefinition = RegisteredTypes.Values.ToArray().Where(x => x.Inference != null && x.Inference.Equals(targetType))
                                     .OrderByDescending(x => x.Priority).FirstOrDefault();
                if (typeDefinition == null)
                {
                    throw new Exception(string.Format("failed to find registered type inferred from interface '{0}'.", targetType.FullName));
                }

                if (typeDefinition.SingletonInstance != null)
                {
                    return(typeDefinition.SingletonInstance);
                }

                return(InternalResolve(typeDefinition.Info as Type));
            }
            else
            {
                return(null);
            }
        }
 protected string CheckRegisteredType() => RegisteredTypes.TryGetValue(Arguments[0], out var type) && ((DataType = type) == type) ? null : $"invalid type '{Arguments[0]}'";