/// <summary> /// Initializes a new instance of ContractServiceAutoMapper class with the specified namespaces, assemblies and strictmode /// </summary> /// <param name="namespaces">The namespaces of services</param> /// <param name="assemblies">The assemblies of services</param> /// <param name="strictMode">The value indicating whether strict mode is on or off</param> public ContractServiceAutoMapper(string[] namespaces, Assembly[] assemblies, bool strictMode) { _namespaces = namespaces; _assemblies = assemblies; _strictMode = strictMode; _mapTable = new ServiceMapTable(); }
private void MapSelectiveBaseAndInterfaceTypes(Type serviceType, ServiceMapTable services, ServiceAttribute serviceAttribute) { #if NET46 /*Fetch implemented interfaces of service whose interface is decorated with ContractAttribute.*/ IEnumerable <Type> interfaces = serviceType.GetInterfaces() .Where(@interface => @interface.GetCustomAttribute <ContractAttribute>() != null); #else /*Fetch implemented interfaces of service whose interface is decorated with ContractAttribute.*/ IEnumerable <Type> interfaces = serviceType.GetInterfaces() .Where(@interface => @interface.GetTypeInfo().GetCustomAttribute <ContractAttribute>() != null); #endif /*Maps the base class (which is decorated with contract attribute) of the service*/ if (serviceType.GetTypeInfo().BaseType != typeof(object)) { //if base type is decorated with contract attribute then add that to service. var baseTypeInfo = serviceType.GetTypeInfo().BaseType.GetTypeInfo(); if (baseTypeInfo.GetCustomAttribute <ContractAttribute>() != null) { MapService(services, interfaceType: serviceType.GetTypeInfo().BaseType, serviceType: serviceType); } } /*Maps the interfaces (which are decorated with contract attribute) of the service */ /*Map service type with the contract interfaces*/ foreach (var interfaceType in interfaces) { MapService(services, interfaceType, serviceType); } /*Maps inherit type (base class/interface) if the type is set to the property contract of ServiceAttribute */ MapServiceDefinedAtAttributeLevel(services, serviceType, serviceAttribute); }
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)); } }
private void MapAllBaseAndInterfaceTypes(Type serviceType, ServiceMapTable services) { //Map base type with the service if (serviceType.GetTypeInfo().BaseType != typeof(object)) { MapService(services, interfaceType: serviceType.GetTypeInfo().BaseType, serviceType: serviceType); } IEnumerable <Type> interfaces = serviceType.GetInterfaces(); /*Maps the interfaces (which are decorated with contract attribute) of the service */ /*Map service type with the contract interfaces*/ foreach (var interfaceType in interfaces) { MapService(services, interfaceType, serviceType); } }
private void MapServiceDefinedAtAttributeLevel(ServiceMapTable services, Type serviceType, ServiceAttribute serviceAttribute) { if (serviceAttribute.Contracts != null) { foreach (var contract in serviceAttribute.Contracts) { if (contract != null) { //First we need to check whether service class is inherited from this contract if (contract.GetTypeInfo().IsAssignableFrom(serviceType)) { MapService(services, contract, serviceType); } } } } }
private void InternalMap(string[] namespaces, Assembly[] aseemblies, ServiceMapTable services) { if (aseemblies == null) { return; } foreach (var asm in aseemblies) { #if NET46 IEnumerable <Type> serviceTypes = from type in asm.GetTypes() where type.GetCustomAttribute <ServiceAttribute>() != null select type; #else IEnumerable <Type> serviceTypes = from type in asm.GetTypes() where type.GetTypeInfo().GetCustomAttribute <ServiceAttribute>() != null select type; #endif FillServicesDictionary(serviceTypes, services, namespaces); } }
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 FillServicesDictionary(IEnumerable <Type> serviceTypes, ServiceMapTable services, string[] namespaces) { foreach (Type serviceType in serviceTypes) { /*Allow when no namespaces are configured or if it's configured then check the namespace of the service is matched with namespaces declared in config via ServiceInjector.*/ if (namespaces == null || namespaces.Length == 0 || namespaces.Contains(serviceType.Namespace)) { var serviceAttribute = serviceType.GetTypeInfo().GetCustomAttributes <ServiceAttribute>().FirstOrDefault(); /*1. First check auto - if auto specified, rest all ignored * 2. Contracts at service attribute level - if contracts specified Individual Interface level contract ignored * 3. Individual Interface level */ if (serviceAttribute.Auto) { MapAllBaseAndInterfaceTypes(serviceType, services); } else { MapSelectiveBaseAndInterfaceTypes(serviceType, services, serviceAttribute); } } } }