Exemple #1
0
        /// <summary>
        /// Adds a default constructor to the singleton type.
        /// </summary>
        /// <param name="module">The module that will host the singleton type.</param>
        /// <param name="singletonName">The name of the singleton.</param>
        /// <param name="typeAttributes">The type attributes that describes the singleton type.</param>
        /// <param name="objectType">The object ty pe.</param>
        /// <returns>A <see cref="TypeDefinition"/> that represents the singleton type.</returns>
        private static TypeDefinition AddDefaultSingletonConstructor(ModuleDefinition module, string singletonName, TypeAttributes typeAttributes, TypeReference objectType)
        {
            // Add a default constructor and make it private
            var singletonType = module.DefineClass(singletonName, "Hiro.Containers.Internal", typeAttributes, objectType);

            singletonType.AddDefaultConstructor();
            var constructor = singletonType.GetDefaultConstructor();

            constructor.IsFamilyOrAssembly = true;

            return(singletonType);
        }
Exemple #2
0
        /// <summary>
        /// Defines the nested type that will instantiate the actual singleton service instance.
        /// </summary>
        /// <param name="module">The module that will host the singleton type.</param>
        /// <param name="singletonType">The singleton type.</param>
        /// <param name="instanceField">The field that will hold the singleton instance.</param>
        /// <param name="serviceMap">The service map that contains the list of dependencies in the application.</param>
        /// <param name="implementation">The implementation that will instantiate the dependency.</param>
        /// <param name="dependency">The dependency that will be instantiated by the singleton.</param>
        /// <param name="targetMethod">The method that will be used to instantiate the actual service instance.</param>
        private void DefineNestedType(ModuleDefinition module, TypeDefinition singletonType, FieldDefinition instanceField, IDictionary <IDependency, IImplementation> serviceMap, IImplementation implementation, IDependency dependency, MethodDefinition targetMethod)
        {
            var objectType = module.ImportType(typeof(object));
            var nestedName = string.Format("Nested-{0}", dependency.GetHashCode());

            const TypeAttributes nestedAttributes = TypeAttributes.NestedFamORAssem | TypeAttributes.Sealed | TypeAttributes.AutoClass | TypeAttributes.Class | TypeAttributes.AnsiClass;
            var nestedType = module.DefineClass(nestedName, "Hiro.Containers.Internal", nestedAttributes, objectType);

            singletonType.NestedTypes.Add(nestedType);

            nestedType.Fields.Add(instanceField);

            // Emit the static constructor body
            var cctor = DefineNestedConstructors(module, nestedType);

            EmitSingletonInstantiation(dependency, implementation, serviceMap, instanceField, cctor, module, targetMethod);
        }
        public TypeDefinition CreateType(string adapterName, string namespaceName, Dictionary <MethodReference, MethodReference> methodMap)
        {
            const TypeAttributes adapterAttributes = TypeAttributes.Public | TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.Class |
                                                     TypeAttributes.BeforeFieldInit;


            var adapterType = _targetModule.DefineClass(adapterName, namespaceName, adapterAttributes,
                                                        _targetModule.ImportType <object>());

            var fieldName   = string.Format("___<>{0}__BackingField", _targetDependency.Name);
            var targetField = new FieldDefinition(fieldName, _targetDependency, FieldAttributes.Private);

            adapterType.Fields.Add(targetField);
            adapterType.Interfaces.Add(_interfaceType);

            _addAdapterConstructor.AddConstructor(adapterType, targetField);

            foreach (var method in _interfaceType.Methods.Cast <MethodDefinition>())
            {
                _addAdapterMethod.AddMethod(adapterType, targetField, method, methodMap);
            }

            return(adapterType);
        }
Exemple #4
0
        /// <summary>
        /// Creates a proxy type using the given
        /// <paramref name="baseType"/> as the base class
        /// and ensures that the proxy type implements the given
        /// interface types.
        /// </summary>
        /// <param name="baseType">The base class from which the proxy type will be derived.</param>
        /// <param name="baseInterfaces">The list of interfaces that the proxy will implement.</param>
        /// <returns>A forwarding proxy.</returns>
        public Type CreateProxyType(Type baseType, IEnumerable <Type> baseInterfaces)
        {
            // Reuse the cached results, if possible
            Type[] originalInterfaces = baseInterfaces.ToArray();
            if (Cache != null && Cache.Contains(baseType, originalInterfaces))
            {
                return(Cache.Get(baseType, originalInterfaces));
            }

            if (!baseType.IsPublic)
            {
                throw new ArgumentException("The proxy factory can only generate proxies from public base classes.",
                                            "baseType");
            }

            bool hasNonPublicInterfaces = (from t in baseInterfaces
                                           where t.IsNotPublic
                                           select t).Count() > 0;

            if (hasNonPublicInterfaces)
            {
                throw new ArgumentException("The proxy factory cannot generate proxies from non-public interfaces.",
                                            "baseInterfaces");
            }

            #region Determine which interfaces need to be implemented

            Type actualBaseType = baseType.IsInterface ? typeof(object) : baseType;
            var  interfaces     = new HashSet <Type>(baseInterfaces);
            // Move the base type into the list of interfaces
            // if the user mistakenly entered
            // an interface type as the base type
            if (baseType.IsInterface)
            {
                interfaces.Add(baseType);
            }

            if (InterfaceExtractor != null)
            {
                // Get the interfaces for the base type
                InterfaceExtractor.GetInterfaces(actualBaseType, interfaces);

                Type[] targetList = interfaces.ToArray();
                // Extract the inherited interfaces
                foreach (Type type in targetList)
                {
                    InterfaceExtractor.GetInterfaces(type, interfaces);
                }
            }

            #endregion

            #region Generate the assembly

            string             assemblyName     = "LinFu.Proxy";
            AssemblyDefinition assembly         = AssemblyFactory.DefineAssembly(assemblyName, AssemblyKind.Dll);
            ModuleDefinition   mainModule       = assembly.MainModule;
            TypeReference      importedBaseType = mainModule.Import(actualBaseType);
            TypeAttributes     attributes       = TypeAttributes.AutoClass | TypeAttributes.Class |
                                                  TypeAttributes.Public | TypeAttributes.BeforeFieldInit;

            #endregion

            #region Initialize the proxy type

            string         guid          = Guid.NewGuid().ToString().Replace("-", "");
            string         typeName      = string.Format("{0}Proxy-{1}", baseType.Name, guid);
            string         namespaceName = "LinFu.Proxy";
            TypeDefinition proxyType     = mainModule.DefineClass(typeName, namespaceName,
                                                                  attributes, importedBaseType);

            proxyType.AddDefaultConstructor();

            #endregion

            if (ProxyBuilder == null)
            {
                throw new NullReferenceException("The 'ProxyBuilder' property cannot be null");
            }

            // Add the list of interfaces to the target type
            foreach (Type interfaceType in interfaces)
            {
                if (!interfaceType.IsInterface)
                {
                    continue;
                }

                TypeReference currentType = mainModule.Import(interfaceType);
                proxyType.Interfaces.Add(currentType);
            }

            // Hand it off to the builder for construction
            ProxyBuilder.Construct(actualBaseType, interfaces, mainModule, proxyType);

            // Verify the assembly, if possible
            if (Verifier != null)
            {
                Verifier.Verify(assembly);
            }

            #region Compile the results

            Assembly compiledAssembly = assembly.ToAssembly();

            IEnumerable <Type> types = null;

            try
            {
                types = compiledAssembly.GetTypes();
            }
            catch (ReflectionTypeLoadException ex)
            {
                types = ex.Types;
            }

            Type result = (from t in types
                           where t != null && t.IsClass
                           select t).FirstOrDefault();

            #endregion

            // Cache the result
            if (Cache != null)
            {
                Cache.Store(result, baseType, originalInterfaces);
            }

            return(result);
        }