private Expression GetObjectFromSelf(Type interfaceType, ServiceRegister registrar, ServiceState state, string serviceName)
        {
            var serviceInfo = GetServiceInfo(interfaceType, serviceName);

            if (serviceInfo == null)
            {
                ExceptionHelper.ThrowContractNotRegisteredException(interfaceType.FullName);
            }

            var instanceCallback = serviceInfo.GetServiceInstanceCallback <object>();

            if (instanceCallback != null)
            {
                throw new Exception("Internal service injection does not support for Func<> delegate.");
            }

            var expression = serviceInfo.GetServiceInstanceExpression();

            if (expression == null)
            {
                expression = CreateConstructorExpression(interfaceType, serviceInfo.ServiceType, registrar, state);
            }

            return(expression);
        }
        private Expression GetDependencyObject(ParameterInfo constrParameter, ServiceRegister registrar, IgnoreAttribute ignoreAttribute, ServiceState state)
        {
            bool ignore = ignoreAttribute?.ParameterNames.Contains(constrParameter.Name) ?? false;

            if (ignore)
            {
                return(Expression.Default(constrParameter.ParameterType));
            }
            else
            {
                var mappedServiceName = GetMappedServiceName(constrParameter);

                /*
                 * if container model is "Single" then it will search within the same container not in dependencies.
                 * if parameter is decorated with FromSelfAttribute, then find object within the current factory */
                if (IsSelfDependent(constrParameter))
                {
                    //Find it in same
                    return(GetObjectFromSelf(constrParameter.ParameterType, registrar, state, mappedServiceName));
                }

                /*if parameter is decorated with FromDependencyAttribute, then find object within the specified factory */
                string factoryName;
                if (HasDependencyAttribute(constrParameter, out factoryName))
                {
                    return(GetObjectFromDependencyFactory(constrParameter.ParameterType, factoryName, registrar, state, mappedServiceName, new TypeContextAttributes(constrParameter.GetCustomAttributes())));
                }

                //let's subcontract take responsibility to create dependency objects
                return(CreateDependency(constrParameter.ParameterType, registrar, state, mappedServiceName, new TypeContextAttributes(constrParameter.GetCustomAttributes())));
            }
        }
        /// <summary>
        /// Create <see cref="Expression"/> for service which is associated with contract.
        /// </summary>
        /// <param name="interfaceType">Type of contract</param>
        /// <param name="register">The ServiceRegister</param>
        /// <param name="state">The ServiceState</param>
        /// <param name="serviceName"></param>
        /// <param name="attributes"></param>
        /// <returns>Returns <see cref="Expression"/> of service constructor.</returns>
        public override Expression Create(Type interfaceType, ServiceRegister register, ServiceState state, string serviceName, TypeContextAttributes attributes)
        {
            if (interfaceType == null)
            {
                throw new ArgumentNullException(nameof(interfaceType));
            }

            //Register current subcontract service with ServiceRegistrar
            //Root service will refresh with the updated service when there's replacement with new service
            register.Register(interfaceType);

            BaseServiceInfo serviceMeta = GetServiceInfo(interfaceType, serviceName);

            if (serviceMeta == null)
            {
                return(SharedFactory.Create(interfaceType, register, state, serviceName, attributes));
            }

            var userdefinedExpression = serviceMeta.GetServiceInstanceExpression();

            if (userdefinedExpression != null)
            {
                return(Expression.Invoke(userdefinedExpression));
            }

            return(CreateConstructorExpression(interfaceType, serviceMeta.ServiceType, register, state) ?? Expression.Default(interfaceType));
        }
Example #4
0
        /// <summary>
        /// Create <see cref="Expression"/> for service which is associated with contract.
        /// </summary>
        /// <param name="interfaceType">Type of contract</param>
        /// <param name="register">The ServiceRegister</param>
        /// <param name="state">The ServiceState</param>
        /// <param name="serviceName"></param>
        /// <param name="attributes"></param>
        /// <returns>Returns <see cref="Expression"/> of service constructor.</returns>
        public override Expression Create(Type interfaceType, ServiceRegister register, ServiceState state, string serviceName, TypeContextAttributes attributes)
        {
            if (interfaceType == null)
            {
                throw new ArgumentNullException(nameof(interfaceType));
            }

            //Register current subcontract service with ServiceRegistrar
            //Root service will refresh with the updated service when there's replacement with new service
            register.Register(interfaceType);

            BaseServiceInfo serviceMeta = GetServiceInfo(interfaceType, serviceName);

            //Throw exception if service meta not found in the service map table
            if (serviceMeta == null)
            {
                if (attributes.HasAttribute(typeof(OptionalAttribute)))
                {
                    return(Expression.Default(interfaceType));
                }
                else
                {
                    ExceptionHelper.ThrowContractNotRegisteredException($"Type '{interfaceType.FullName}' was not registered with dependency container or shared container.");
                }
            }

            var userdefinedExpression = serviceMeta.GetServiceInstanceExpression();

            if (userdefinedExpression != null)
            {
                return(Expression.Invoke(userdefinedExpression));
            }

            return(CreateConstructorExpression(interfaceType, serviceMeta.ServiceType, register, state) ?? Expression.Default(interfaceType));
        }
 /// <summary>
 /// Creates dependency <see cref="Expression"/> object. if no dependency factory is set and shared factory exists then
 /// creates dependency from the shared factory; otherwise creates from the dependency factory.
 /// </summary>
 /// <param name="interfaceType">The type of the contract.</param>
 /// <param name="register">The service register object.</param>
 /// <param name="state">The service state.</param>
 /// <param name="serviceName"></param>
 /// <param name="attributes"></param>
 /// <returns>Dependency expression</returns>
 protected virtual Expression CreateDependency(Type interfaceType, ServiceRegister register, ServiceState state, string serviceName, TypeContextAttributes attributes)
 {
     //let's subcontract take responsibility to create dependency objects
     if (DependencyFactory == null && SharedFactory != null)
     {
         return(SharedFactory.Create(interfaceType, register, state, serviceName, attributes) ?? Expression.Default(interfaceType));
     }
     return(DependencyFactory?.Create(interfaceType, register, state, serviceName, attributes) ?? Expression.Default(interfaceType));
 }
Example #6
0
        /// <summary>
        /// Initializes new register for the specified interface type.
        /// </summary>
        /// <param name="interfaceType"></param>
        /// <param name="notifier"></param>
        /// <returns></returns>
        public ServiceRegister InitNewRegister(Type interfaceType, IServiceNotifier notifier)
        {
            _register = new ServiceRegister();
            //Register self
            _register.Register(interfaceType);

            notifier.ServiceUpdateNofication += ServiceUpdateNofication;

            return(_register);
        }
        private Expression GetObjectFromDependencyFactory(Type interfaceType, string factoryName, ServiceRegister registrar, ServiceState state, string mappedServiceName, TypeContextAttributes attributes)
        {
            var subcontractFactory = ServiceProviderHelper.GetDependencyFactory(DependencyFactory, factoryName);

            return(subcontractFactory?.Create(interfaceType, registrar, state, mappedServiceName, attributes) ?? Expression.Default(interfaceType));
        }
        /// <summary>
        /// Creates expression object for specified service type constructor.
        /// </summary>
        /// <param name="interfaceType"></param>
        /// <param name="serviceType"></param>
        /// <param name="registrar"></param>
        /// <param name="state"></param>
        /// <returns></returns>
        protected virtual Expression CreateConstructorExpression(Type interfaceType, Type serviceType, ServiceRegister registrar, ServiceState state)
        {
            VerifyNull(interfaceType, nameof(interfaceType));
            VerifyNull(serviceType, nameof(serviceType));
            VerifyNull(registrar, nameof(registrar));
            VerifyNull(state, nameof(state));

            ConstructorInfo[] serviceConstructors = serviceType.GetConstructors();
            ConstructorInfo   serviceConstructor  = GetEligibleConstructorToInvoke(serviceConstructors);

            if (serviceConstructor != null)
            {
                Type[] reusableDependencies = GetReuseDependencies(serviceConstructor);

                /* Get IgnoreAttribute for the constructor, find the constructor parameters
                 * with the specified names, if parameter name is matched  then set NULL to the parameter. */
                var ignoreAttribute = serviceConstructor.GetCustomAttribute <IgnoreAttribute>();

                /*Get parameters of service's constructor and inject corresponding repositories values to it */
                ParameterInfo[] constructorParametersInfo = serviceConstructor.GetParameters();
                Expression[]    arguments = new Expression[constructorParametersInfo.Length];

                int index = 0;
                foreach (ParameterInfo constrParameter in constructorParametersInfo)
                {
                    //if current parameter type is listed under reusable type, then get the expression
                    Expression reuseDependency = GetReuseDependencyIfExists(state, constrParameter.ParameterType);
                    if (reuseDependency != null)
                    {
                        arguments[index] = reuseDependency;
                    }
                    else
                    {
                        var dependencyArgument = GetDependencyObject(constrParameter, registrar, ignoreAttribute, state);

                        //maintain state, if the parameter is listed in reusable list
                        arguments[index] = MaintainState(reusableDependencies, state, constrParameter.ParameterType, dependencyArgument);
                    }

                    index++;
                }
                return(Expression.New(serviceConstructor, arguments));
            }

            //Default constructor
            return(Expression.New(serviceType));
        }
 /// <summary>
 /// Create <see cref="Expression"/> for service which is associated with contract.
 /// </summary>
 /// <param name="interfaceType">Type of contract</param>
 /// <param name="register">The ServiceRegister</param>
 /// <param name="state">The ServiceState</param>
 /// <param name="serviceName"></param>
 /// <param name="attributes"></param>
 /// <returns>Returns <see cref="Expression"/> of service constructor.</returns>
 public abstract Expression Create(Type interfaceType, ServiceRegister register, ServiceState state, string serviceName, TypeContextAttributes attributes);
Example #10
0
 /// <summary>
 /// Creates dependency <see cref="Expression"/> object. if no dependency factory is set and shared factory exists then
 /// creates dependency from the shared factory; otherwise creates from the dependency factory.
 /// </summary>
 /// <param name="interfaceType">The type of the contract.</param>
 /// <param name="register">The service register object.</param>
 /// <param name="state">The service state.</param>
 /// <param name="serviceName"></param>
 /// <param name="attributes"></param>
 /// <returns>Dependency expression</returns>
 protected override Expression CreateDependency(Type interfaceType, ServiceRegister register, ServiceState state, string serviceName, TypeContextAttributes attributes)
 {
     return(Create(interfaceType, register, state, serviceName, attributes) ?? Expression.Default(interfaceType));
 }