Ejemplo n.º 1
0
        /// <summary>
        /// Compiles a dependency graph into an IOC container.
        /// </summary>
        /// <param name="dependencyContainer">The <see cref="IDependencyContainer"/> instance that contains the services that will be instantiated by compiled container.</param>
        /// <param name="typeName">The name of the <see cref="IMicroContainer"/> type.</param>
        /// <param name="namespaceName">The namespace name that will be associated with the container type.</param>
        /// <param name="assemblyName">The name of the assembly that will contain the container type.</param>
        /// <returns>An assembly containing the compiled IOC container.</returns>
        public AssemblyDefinition Compile(string typeName, string namespaceName, string assemblyName, IDependencyContainer dependencyContainer)
        {
            var containerType = _createContainerType.CreateContainerType(typeName, namespaceName, assemblyName);
            var module        = containerType.Module;
            var assembly      = module.Assembly;

            var hashEmitter    = new ServiceHashEmitter();
            var getServiceHash = hashEmitter.AddGetServiceHashMethodTo(containerType, false);

            var fieldType       = module.Import(typeof(Dictionary <int, int>));
            var fieldEmitter    = new FieldBuilder();
            var jumpTargetField = fieldEmitter.AddField(containerType, "__jumpTargets", fieldType);
            var serviceMap      = _serviceMapBuilder.GetAvailableServices(dependencyContainer);
            var jumpTargets     = new Dictionary <IDependency, int>();

            // Map the switch labels in the default constructor
            AddJumpEntries(module, jumpTargetField, containerType, getServiceHash, serviceMap, jumpTargets);

            var defaultConstructor = containerType.GetDefaultConstructor();
            var body = defaultConstructor.Body;
            var il   = body.GetILProcessor();

            AddInitializationMap(containerType, module, fieldEmitter);

            InitializeContainerPlugins(module, dependencyContainer, il);

            il.Emit(OpCodes.Ret);

            _containsMethodImplementor.DefineContainsMethod(containerType, module, getServiceHash, jumpTargetField);
            _getInstanceMethodImplementor.DefineGetInstanceMethod(containerType, module, getServiceHash, jumpTargetField, serviceMap);
            _getAllInstancesMethodImplementor.DefineGetAllInstancesMethod(containerType, module, serviceMap);

            // Remove the NextContainer property stub
            var targetMethods = new List <MethodDefinition>();

            foreach (MethodDefinition method in containerType.Methods)
            {
                var methodName = method.Name;

                if (methodName == "get_NextContainer" || methodName == "set_NextContainer")
                {
                    targetMethods.Add(method);
                }
            }

            targetMethods.ForEach(m => containerType.Methods.Remove(m));

            // Add the NextContainer property
            containerType.AddProperty("NextContainer", typeof(IMicroContainer));

            return(assembly);
        }
Ejemplo n.º 2
0
        public void ShouldCreateJumpEntryFieldInTargetType()
        {
            var assembly = _assemblyBuilder.CreateAssembly(Guid.NewGuid().ToString(), ModuleKind.Dll);
            var module   = assembly.MainModule;

            var            objectType  = module.ImportType(typeof(object));
            var            typeBuilder = new TypeBuilder();
            TypeDefinition targetType  = typeBuilder.CreateType(Guid.NewGuid().ToString(), "Test", objectType, assembly);

            var entryDictionaryType = module.ImportType <Dictionary <int, int> >();
            var entryBuilder        = new FieldBuilder();
            var targetField         = entryBuilder.AddField(targetType, "___jumpEntries", entryDictionaryType);

            // The type should have a field that is a Dictionary<int, int>
            Assert.IsNotNull(targetField);
            Assert.AreEqual(targetField.FieldType, entryDictionaryType);
        }
Ejemplo n.º 3
0
 public static FieldBuilder Add(string name) => FieldBuilder.AddField(name);
Ejemplo n.º 4
0
        /// <summary>
        /// Compiles a dependency graph into an IOC container.
        /// </summary>
        /// <param name="dependencyContainer">The <see cref="IDependencyContainer"/> instance that contains the services that will be instantiated by compiled container.</param>
        /// <param name="typeName">The name of the <see cref="IMicroContainer"/> type.</param>
        /// <param name="namespaceName">The namespace name that will be associated with the container type.</param>
        /// <param name="assemblyName">The name of the assembly that will contain the container type.</param>
        /// <returns>An assembly containing the compiled IOC container.</returns>
        public AssemblyDefinition Compile(string typeName, string namespaceName, string assemblyName, IDependencyContainer dependencyContainer)
        {
            var containerType = _createContainerType.CreateContainerType(typeName, namespaceName, assemblyName);
            var module = containerType.Module;
            var assembly = module.Assembly;

            var hashEmitter = new ServiceHashEmitter();
            var getServiceHash = hashEmitter.AddGetServiceHashMethodTo(containerType, false);

            var fieldType = module.Import(typeof(Dictionary<int, int>));
            var fieldEmitter = new FieldBuilder();
            var jumpTargetField = fieldEmitter.AddField(containerType, "__jumpTargets", fieldType);
            var serviceMap = _serviceMapBuilder.GetAvailableServices(dependencyContainer);
            var jumpTargets = new Dictionary<IDependency, int>();

            // Map the switch labels in the default constructor
            AddJumpEntries(module, jumpTargetField, containerType, getServiceHash, serviceMap, jumpTargets);

            var defaultConstructor = containerType.GetDefaultConstructor();
            var body = defaultConstructor.Body;
            var il = body.GetILProcessor();

            AddInitializationMap(containerType, module, fieldEmitter);

            InitializeContainerPlugins(module, dependencyContainer, il);

            il.Emit(OpCodes.Ret);

            _containsMethodImplementor.DefineContainsMethod(containerType, module, getServiceHash, jumpTargetField);
            _getInstanceMethodImplementor.DefineGetInstanceMethod(containerType, module, getServiceHash, jumpTargetField, serviceMap);
            _getAllInstancesMethodImplementor.DefineGetAllInstancesMethod(containerType, module, serviceMap);

            // Remove the NextContainer property stub
            var targetMethods = new List<MethodDefinition>();
            foreach (MethodDefinition method in containerType.Methods)
            {
                var methodName = method.Name;

                if (methodName == "get_NextContainer" || methodName == "set_NextContainer")
                    targetMethods.Add(method);
            }

            targetMethods.ForEach(m => containerType.Methods.Remove(m));

            // Add the NextContainer property
            containerType.AddProperty("NextContainer", typeof(IMicroContainer));

            return assembly;
        }