/// <summary> /// Emits the instructions that will instantiate the current implementation. /// </summary> /// <param name="dependency">The dependency that describes the service to be instantiated.</param> /// <param name="serviceMap">The service map that contains the list of dependencies in the application.</param> /// <param name="targetMethod">The target method.</param> public void Emit(IDependency dependency, IDictionary <IDependency, IImplementation> serviceMap, MethodDefinition targetMethod) { var declaringType = targetMethod.DeclaringType; var module = declaringType.Module; var listType = typeof(List <>).MakeGenericType(_serviceType); var listCtor = module.ImportConstructor(listType, new System.Type[0]); var listVariable = targetMethod.AddLocal(listType); var IL = targetMethod.GetILGenerator(); IL.Emit(OpCodes.Newobj, listCtor); IL.Emit(OpCodes.Stloc, listVariable); var targetDependencies = (from d in serviceMap.Keys where d.ServiceType == _serviceType select d).ToArray(); var addItem = module.ImportMethod("Add", listType); var serviceType = module.Import(_serviceType); var currentService = targetMethod.AddLocal(_serviceType); foreach (var currentDependency in targetDependencies) { IL.Emit(OpCodes.Ldloc, listVariable); // Instantiate the current service type var implementation = new ContainerCall(currentDependency.ServiceType, currentDependency.ServiceName); implementation.Emit(currentDependency, serviceMap, targetMethod); IL.Emit(OpCodes.Isinst, serviceType); IL.Emit(OpCodes.Stloc, currentService); // Call IInitialize.Initialize(container) on the current service type _initializer.Initialize(IL, module, currentService); IL.Emit(OpCodes.Ldloc, currentService); IL.Emit(OpCodes.Callvirt, addItem); } var enumerableType = typeof(IEnumerable <>).MakeGenericType(_serviceType); var importedEnumerableType = module.Import(enumerableType); IL.Emit(OpCodes.Ldloc, listVariable); IL.Emit(OpCodes.Isinst, importedEnumerableType); }
/// <summary> /// Emits the instructions that will instantiate the current implementation. /// </summary> /// <param name="dependency">The dependency that describes the service to be instantiated.</param> /// <param name="serviceMap">The service map that contains the list of dependencies in the application.</param> /// <param name="targetMethod">The target method.</param> public void Emit(IDependency dependency, IDictionary<IDependency, IImplementation> serviceMap, MethodDefinition targetMethod) { var declaringType = targetMethod.DeclaringType; var module = declaringType.Module; var listType = typeof(List<>).MakeGenericType(_serviceType); var listCtor = module.ImportConstructor(listType, new Type[0]); var listVariable = targetMethod.AddLocal(listType); var IL = targetMethod.GetILGenerator(); IL.Emit(OpCodes.Newobj, listCtor); IL.Emit(OpCodes.Stloc, listVariable); var targetDependencies = (from d in serviceMap.Keys where d.ServiceType == _serviceType select d).ToArray(); var addItem = module.ImportMethod("Add", listType); var serviceType = module.Import(_serviceType); var currentService = targetMethod.AddLocal(_serviceType); foreach(var currentDependency in targetDependencies) { IL.Emit(OpCodes.Ldloc, listVariable); // Instantiate the current service type var implementation = new ContainerCall(currentDependency.ServiceType, currentDependency.ServiceName); implementation.Emit(currentDependency, serviceMap, targetMethod); IL.Emit(OpCodes.Isinst, serviceType); IL.Emit(OpCodes.Stloc, currentService); // Call IInitialize.Initialize(container) on the current service type _initializer.Initialize(IL, module, currentService); IL.Emit(OpCodes.Ldloc, currentService); IL.Emit(OpCodes.Callvirt, addItem); } var enumerableType = typeof(IEnumerable<>).MakeGenericType(_serviceType); var importedEnumerableType = module.Import(enumerableType); IL.Emit(OpCodes.Ldloc, listVariable); IL.Emit(OpCodes.Isinst, importedEnumerableType); }
/// <summary> /// Emits the <see cref="IFactory{T}.Create"/> method call that will instantiate the current service instance. /// </summary> /// <param name="dependency">The dependency that describes the service to be instantiated.</param> /// <param name="serviceMap">The service map that contains the list of dependencies in the application.</param> /// <param name="targetMethod">The target method.</param> public void Emit(IDependency dependency, IDictionary<IDependency, IImplementation> serviceMap, MethodDefinition targetMethod) { var factoryType = typeof (IFactory<>).MakeGenericType(_serviceType); var getFactoryInstanceCall = new ContainerCall(factoryType, _serviceName); var factoryName = _serviceName; getFactoryInstanceCall.Emit(new Dependency(factoryType, factoryName), serviceMap, targetMethod); var declaringType = targetMethod.DeclaringType; var module = declaringType.Module; var factoryTypeReference = module.Import(factoryType); var createMethod = module.Import(factoryType.GetMethod("Create")); var IL = targetMethod.GetILGenerator(); IL.Emit(OpCodes.Isinst, factoryTypeReference); IL.Emit(OpCodes.Callvirt, createMethod); }
/// <summary> /// Emits the <see cref="IFactory{T}.Create"/> method call that will instantiate the current service instance. /// </summary> /// <param name="dependency">The dependency that describes the service to be instantiated.</param> /// <param name="serviceMap">The service map that contains the list of dependencies in the application.</param> /// <param name="targetMethod">The target method.</param> public void Emit(IDependency dependency, IDictionary <IDependency, IImplementation> serviceMap, MethodDefinition targetMethod) { var factoryType = typeof(IFactory <>).MakeGenericType(_serviceType); var getFactoryInstanceCall = new ContainerCall(factoryType, _serviceName); var factoryName = _serviceName; getFactoryInstanceCall.Emit(new Dependency(factoryType, factoryName), serviceMap, targetMethod); var declaringType = targetMethod.DeclaringType; var module = declaringType.Module; var factoryTypeReference = module.Import(factoryType); var createMethod = module.Import(factoryType.GetMethod("Create")); var IL = targetMethod.GetILGenerator(); IL.Emit(OpCodes.Isinst, factoryTypeReference); IL.Emit(OpCodes.Callvirt, createMethod); }