/// <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); } } } }
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)); } }
/// <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); } }
/// <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); }
/// <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)); }
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); }