Exemplo 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);
        }
Exemplo n.º 2
0
        public void ShouldBeAbleToCreatePrivateStaticGetServiceHashCodeMethodForAGivenType()
        {
            var assembly = _assemblyBuilder.CreateAssembly(Guid.NewGuid().ToString(), ModuleKind.Dll);
            var module   = assembly.MainModule;

            TypeReference baseType = module.Import(typeof(object));

            var typeBuilder = new TypeBuilder();
            var newType     = typeBuilder.CreateType("Test", "Test", baseType, assembly);

            var emitter = new ServiceHashEmitter();

            emitter.AddGetServiceHashMethodTo(newType, true);

            var result = (from MethodDefinition m in newType.Methods
                          where m.Name == "GetServiceHashCode"
                          select m).First();

            Assert.IsNotNull(result);

            // Load the assembly
            var loadedAssembly = assembly.ToAssembly();

            var containerType = loadedAssembly.GetTypes()[0];
            var targetMethod  = containerType.GetMethod("GetServiceHashCode", BindingFlags.Public | BindingFlags.Static);

            Assert.IsNotNull(targetMethod);

            var serviceName = "Test";
            var serviceType = typeof(IVehicle);

            // The GetServiceHashCode method result should match the actual hash
            var expectedHash = serviceName.GetHashCode() ^ serviceType.GetHashCode();
            var actualHash   = targetMethod.Invoke(null, new object[] { serviceType, serviceName });

            Assert.AreEqual(expectedHash, actualHash);
        }