/// <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));
        }
        /// <summary>
        /// Executes before initiating the service instance.
        /// </summary>
        /// <param name="contractType"></param>
        /// <param name="serviceName"></param>
        /// <returns></returns>
        protected InvocationInfo BeforeInvoke(Type contractType, string serviceName)
        {
            var             factory     = _internalsm.GetServiceFactory();
            BaseServiceInfo serviceInfo = factory.GetServiceInfo(contractType, serviceName);

            if (serviceInfo == null)
            {
                return(default(InvocationInfo));
            }

            //Invoke if there are any decorators.
            if (DecoratorManager.GlobalDecorators.Count > 0 || (serviceInfo.Decorators != null && serviceInfo.Decorators.Length > 0))
            {
                ServiceCallContext callContext = ServiceCallContext.Create(contractType, serviceInfo.ServiceType, this);
                InvokeDecorator(callContext, InvocationCase.Before, serviceInfo.Decorators);

                return(new InvocationInfo()
                {
                    ServiceInfo = serviceInfo, ServiceCallContext = callContext
                });
            }

            return(new InvocationInfo()
            {
                ServiceInfo = serviceInfo
            });
        }
        public void Compile <T>(Type interfaceType, BaseServiceInfo serviceMeta, Func <Type, Type, ServiceRegister, ServiceState, Expression> createConstructorExpression) where T : class
        {
            if (serviceMeta.Activator == null)
            {
                lock (serviceMeta.SyncObject)
                {
                    if (serviceMeta.Activator == null)
                    {
                        var registrar = serviceMeta.InitNewRegister(interfaceType, _notifier);

                        Func <T> serviceCreator = serviceMeta.GetServiceInstanceCallback <T>();
                        if (serviceCreator == null)
                        {
                            var        state         = new ServiceState(); /*Root place for service state instance*/
                            Expression newExpression = createConstructorExpression(interfaceType, serviceMeta.ServiceType, registrar, state);

                            var blockExpression = BuildExpression(state, newExpression);

                            //Set Activator
                            serviceCreator = Expression.Lambda <Func <T> >(blockExpression).Compile();
                        }
                        serviceMeta.Activator = new ServiceActivator <T>(serviceCreator, serviceMeta.IsReusable);
                    }
                }
            }
        }
Example #4
0
        private void MapWithExistingService(ServiceAttribute serviceAttribute, ServiceMapTable services, Type interfaceType, Type serviceType)
        {
            var mapInfo = services[interfaceType];

            //Duplicate Service exception check for default service
            if (_strictMode && string.IsNullOrEmpty(serviceAttribute.Name) && mapInfo.DefaultService != null)
            {
                ExceptionHelper.ThrowDuplicateServiceException($"{serviceType.FullName} implements {interfaceType.FullName}");
            }
            //Set default service if service name is not set
            if (string.IsNullOrEmpty(serviceAttribute.Name))
            {
                mapInfo.DefaultService = new ServiceInfo(serviceType, BaseServiceInfo.GetDecorators(interfaceType));
            }
            else //named service
            {
                if (mapInfo.Services == null)
                {
                    mapInfo.Services = new ServicesPoint();
                }
                if (_strictMode)
                {
                    //Duplicate Service exception check for named services
                    if (mapInfo.Services.ContainsKey(serviceAttribute.Name))
                    {
                        ExceptionHelper.ThrowDuplicateServiceException($"{serviceType.FullName} implements {interfaceType.FullName}");
                    }
                }
                mapInfo.Services[serviceAttribute.Name] = new ServiceInfo(serviceType, BaseServiceInfo.GetDecorators(interfaceType));
            }
        }
Example #5
0
        /// <summary>
        /// Add or replace if exists <paramref name="contractType"/> and <paramref name="serviceMeta"/> to the collection.
        /// </summary>
        /// <param name="contractType"></param>
        /// <param name="serviceMeta"></param>
        public void AddOrReplace(Type contractType, BaseServiceInfo serviceMeta)
        {
            if (serviceMeta.ServiceType != null && !CanTypeCast(contractType, serviceMeta.ServiceType))
            {
                ExceptionHelper.ThrowInvalidServiceType(contractType, serviceMeta.ServiceType);
            }

            if (_mapTable.ContainsKey(contractType))
            {
                if (string.IsNullOrEmpty(serviceMeta.ServiceName))
                {
                    _mapTable[contractType].DefaultService = serviceMeta;
                }
                else
                {
                    if (_mapTable[contractType].Services == null)
                    {
                        _mapTable[contractType].Services = new ServicesPoint();
                    }
                    _mapTable[contractType].Services[serviceMeta.ServiceName] = serviceMeta;
                }
            }
            else
            {
                Add(contractType, serviceMeta);
            }
        }
Example #6
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));
        }
        private void ReplaceServiceInternal <T>(Type service, string serviceName) where T : class
        {
            Type interfaceType = typeof(T);

            ServicesMapTable.AddOrReplace(interfaceType, new ServiceInfo(service, BaseServiceInfo.GetDecorators(interfaceType), serviceName));

            //send update to observer
            ContractObserver.Update(interfaceType);
        }
        private void ReplaceServiceInternal <TC>(Expression <Func <TC> > expression, string serviceName) where TC : class
        {
            Type interfaceType = typeof(TC);
            var  serviceMeta   = new ServiceInfo <TC, TC>(expression, BaseServiceInfo.GetDecorators(interfaceType), serviceName);

            ServicesMapTable.AddOrReplace(interfaceType, serviceMeta);

            //send update to observer
            ContractObserver.Update(interfaceType);
        }
        private IRootContainer AddInternal <TC>(Func <TC> serviceAction, string serviceName) where TC : class
        {
            Type interfaceType = typeof(TC);
            var  serviceMeta   = new ServiceInfo <TC, TC>(serviceAction, BaseServiceInfo.GetDecorators(interfaceType), serviceName);

            ServicesMapTable.Add(interfaceType, serviceMeta);

            //send update to observer
            ContractObserver.Update(interfaceType);

            return(this);
        }
 /// <summary>
 /// Creates associated service instance of specified contract.
 /// </summary>
 /// <param name="contractType"></param>
 /// <param name="serviceMeta"></param>
 /// <returns></returns>
 public object Create(Type contractType, BaseServiceInfo serviceMeta)
 {
     if (serviceMeta != null)
     {
         if (serviceMeta.Activator == null)
         {
             //Compile
             _compiler.Compile <object>(contractType, serviceMeta, CreateConstructorExpression);
         }
         return(serviceMeta.Activator.CreateInstance <object>());
     }
     return(null);
 }
        /// <summary>
        /// Returns <see cref="BaseServiceInfo"/> object, if service is null then it returns default service info.
        /// </summary>
        /// <param name="interfaceType"></param>
        /// <param name="serviceName"></param>
        /// <returns></returns>
        protected BaseServiceInfo GetServiceInfo(Type interfaceType, string serviceName)
        {
            BaseServiceInfo serviceInfo = null;

            if (!string.IsNullOrEmpty(serviceName))
            {
                serviceInfo = ServicesMapTable[interfaceType, serviceName];
            }
            else
            {
                serviceInfo = ServicesMapTable[interfaceType];
            }
            return(serviceInfo);
        }
Example #12
0
        /// <summary>
        /// Adds the specified <paramref name="contractType"/> and <paramref name="serviceMeta"/> to the mapper.
        /// </summary>
        /// <param name="contractType"></param>
        /// <param name="serviceMeta"></param>
        public void Add(Type contractType, BaseServiceInfo serviceMeta)
        {
            if (serviceMeta.ServiceType != null && !CanTypeCast(contractType, serviceMeta.ServiceType))
            {
                ExceptionHelper.ThrowInvalidServiceType(contractType, serviceMeta.ServiceType);
            }

            if (string.IsNullOrEmpty(serviceMeta.ServiceName)) //if there's no default service
            {
                if (_mapTable.ContainsKey(contractType))
                {
                    if (_mapTable[contractType].DefaultService != null)
                    {
                        var msg = $"An element with the key '{contractType.FullName}' already exists.";
                        ExceptionHelper.ThrowArgumentException(msg);
                    }
                    _mapTable[contractType].DefaultService = serviceMeta;
                }
                else
                {
                    _mapTable.Add(contractType, new ServiceMapInfo()
                    {
                        DefaultService = serviceMeta
                    });
                }
            }
            else
            {
                if (_mapTable.ContainsKey(contractType))
                {
                    _mapTable[contractType].CreateServicesIfNotInitialized();
                    if (_mapTable[contractType].Services.ContainsKey(serviceMeta.ServiceName))
                    {
                        var msg = $"An element with the key '{contractType.FullName}' already exists.";
                        ExceptionHelper.ThrowArgumentException(msg);
                    }
                    _mapTable[contractType].Services.Add(serviceMeta.ServiceName, serviceMeta);
                }
                else
                {
                    _mapTable.Add(contractType, new ServiceMapInfo()
                    {
                        Services = new ServicesPoint()
                        {
                            [serviceMeta.ServiceName] = serviceMeta
                        }
                    });
                }
            }
        }
 /// <summary>
 /// Creates associated service instance of specified contract <typeparamref name="T"/>.
 /// </summary>
 /// <typeparam name="T">Specify contact type.</typeparam>
 /// <param name="serviceMeta"></param>
 /// <returns></returns>
 public virtual T Create <T>(BaseServiceInfo serviceMeta) where T : class
 {
     if (serviceMeta != null)
     {
         if (serviceMeta.Activator == null)
         {
             Type interfaceType = typeof(T);
             //Compile
             _compiler.Compile <T>(interfaceType, serviceMeta, CreateConstructorExpression);
         }
         return(serviceMeta.Activator.CreateInstance <T>());
     }
     return(default(T));
 }
Example #14
0
        private void MapService(ServiceMapTable services, Type interfaceType, Type serviceType)
        {
            /*Check for ServiceAttribute, if not found, we don't need to process */
            var serviceAttribute = serviceType.GetTypeInfo().GetCustomAttributes <ServiceAttribute>().FirstOrDefault();

            if (serviceAttribute == null)
            {
                return;
            }

            /*if the contract already exists in the services collection, try to update the services.
             * if strict mode is enabled and service already exists then it throw an exception, otherwise it updates.
             * if service name is not specified then it will be consider as DefaultService
             */
            if (services.ContainsKey(interfaceType))
            {
                MapWithExistingService(serviceAttribute, services, interfaceType, serviceType);
            }
            else
            {
                //If service name is not specified then add it as default service
                if (string.IsNullOrEmpty(serviceAttribute.Name))
                {
                    services.Add(interfaceType, new ServiceMapInfo()
                    {
                        DefaultService = new ServiceInfo(serviceType, BaseServiceInfo.GetDecorators(interfaceType))
                    });
                }
                else
                {
                    services.Add(interfaceType, new ServiceMapInfo()
                    {
                        Services = new ServicesPoint()
                        {
                            [serviceAttribute.Name] = new ServiceInfo(serviceType, BaseServiceInfo.GetDecorators(interfaceType))
                        }
                    });
                }
            }
        }
        private void ReplaceSingletonServiceInternal <TC, TS>(string serviceName) where TC : class where TS : TC
        {
            Type interfaceType = typeof(TC);
            var  serviceMeta   = new ServiceInfo <TC, TS>(isReusable: true, decorators: BaseServiceInfo.GetDecorators(interfaceType), serviceName: serviceName);

            ServicesMapTable.AddOrReplace(interfaceType, serviceMeta);

            //send update to observer
            ContractObserver.Update(interfaceType);
        }