示例#1
0
        public void TransientsAreNotStored()
        {
            var registeredType = new RegisteredType(typeof(MockClass), LifeCycle.Transient, Ctor, ctorParams);
            var myClass        = registeredType.CreateInstance();

            Assert.Null(registeredType.Instance);
        }
示例#2
0
        private object CreateInstance(Type type, RegisteredType registeredType)
        {
            if (_stack.Contains(type))
            {
                throw new Exception("circular dependency");
            }

            _stack.Push(type);

            var instanceType = registeredType.Implementation;

            if (instanceType.IsGenericTypeDefinition)
            {
                instanceType = instanceType.MakeGenericType(type.GenericTypeArguments);
            }

            var constructor = instanceType.GetConstructors()
                              .OrderByDescending(x => x.GetParameters().Length)
                              .FirstOrDefault();

            var parameters = GetConstructorParameters(constructor);

            registeredType.Instance = Activator.CreateInstance(instanceType, parameters);

            _stack.Pop();

            return(registeredType.Instance);
        }
示例#3
0
        public void SingletonsAreStored()
        {
            var registeredType = new RegisteredType(typeof(MockClass), LifeCycle.Singleton, Ctor, ctorParams);
            var myClass        = registeredType.CreateInstance();

            Assert.Equal(myClass, registeredType.Instance);
        }
        private RegisteredType RegisterType(Type dependencyType, Type implementationType)
        {
            CheckImplementationType(implementationType);

            var registerType = new RegisteredType()
            {
                Dependency     = dependencyType,
                Implementation = implementationType
            };

            if (_container.TryGetValue(dependencyType, out var registeredTypes))
            {
                if (registeredTypes.All(x => x.Implementation != implementationType))
                {
                    registeredTypes.Add(registerType);
                }
            }
            else
            {
                _container.Add(dependencyType, new List <RegisteredType>()
                {
                    registerType
                });
            }

            return(registerType);
        }
示例#5
0
        // SETUP

        public static void RegisterType <TAssetType>(string extension) where TAssetType : class, IAsset
        {
            // Check valid constructor exists
            bool compound;
            var  assetType = typeof(TAssetType);

            if (typeof(IBasicAsset).IsAssignableFrom(assetType))
            {
                compound = false;
                var constructor = assetType.GetConstructor(new Type[] {
                    typeof(string),
                    typeof(IFileStore)
                });
                if (constructor == null)
                {
                    throw new ArgumentException("Type " + assetType.Name + " does not have required constructor");
                }
            }
            else if (typeof(ICompoundAsset).IsAssignableFrom(assetType))
            {
                compound = true;
                var constructor = assetType.GetConstructor(new Type[] {
                    typeof(string)
                });
                if (constructor == null)
                {
                    throw new ArgumentException("Type " + assetType.Name + " does not have required constructor");
                }
            }
            else
            {
                throw new ArgumentException("Type " + assetType.Name + " is not " + typeof(IBasicAsset).Name + " or " + typeof(ICompoundAsset).Name);
            }

            // Check not already registered
            if (s_extensionToRegisteredType.ContainsKey(extension))
            {
                throw new ArgumentException("Extension " + extension + " is already registered to type " + s_extensionToRegisteredType[extension].Type.Name);
            }
            if (s_typeToRegisteredType.ContainsKey(assetType))
            {
                throw new ArgumentException("Type " + assetType.Name + " is already registered to extension " + s_typeToRegisteredType[assetType].Extension);
            }

            // Register
            var registeredType = new RegisteredType();

            registeredType.Type      = assetType;
            registeredType.Extension = extension;
            registeredType.Compound  = compound;

            s_extensionToRegisteredType.Add(extension, registeredType);
            s_typeToRegisteredType.Add(assetType, registeredType);
            while (assetType.BaseType != typeof(object))
            {
                s_typeToRegisteredType.Add(assetType.BaseType, registeredType);
                assetType = assetType.BaseType;
            }
        }
示例#6
0
 /// <summary>
 /// Registers a concrete type for a given interface type
 /// </summary>
 /// <typeparam name="TTypeToResolve">Interface type to be fulfilled</typeparam>
 /// <param name="concreteType">Concrete (actual) type fulfilling the given interface type</param>
 /// <param name="isSingleton">True if the factory is to make only one of these contrete types</param>
 /// <param name="constructorParameterTypes">Interface types that serve as constructor parameters for this type;
 /// they must be resolvable by this factory</param>
 public void Register <TTypeToResolve>(Type concreteType, bool isSingleton = false, params Type[] constructorParameterTypes)
 {
     _registry[typeof(TTypeToResolve)] = new RegisteredType
     {
         ConcreteType = concreteType,
         IsSingleton  = isSingleton,
         ConstructorParameterTypes = constructorParameterTypes,
     };
 }
示例#7
0
        public object GetInstance(RegisteredType registered, object[] arguments = null)
        {
            if (registered.LifeCycle == LifeCycle.Transient)
            {
                return(GetNewInstance(registered.ObjectType, arguments));
            }

            return(GetSingleton(registered.ObjectType, arguments));
        }
示例#8
0
        private object GetInstance(Type type, RegisteredType registeredType)
        {
            if (registeredType.IsSingleton &&
                registeredType.Instance != null)
            {
                return(registeredType.Instance);
            }

            return(CreateInstance(type, registeredType));
        }
示例#9
0
        private object ObjectFromRegisteredType(RegisteredType registeredType)
        {
            var parameterList = new List <object>();

            foreach (var constructorParameterType in registeredType.ConstructorParameterTypes)
            {
                parameterList.Add(Resolve(constructorParameterType));
            }

            return(Activator.CreateInstance(registeredType.ConcreteType, parameterList.ToArray()));
        }
示例#10
0
        /// <summary>
        /// Returns a hash code for this instance.
        /// </summary>
        /// <returns>A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.</returns>
        public override int GetHashCode()
        {
            var hashCode = Constants.HashInitializer;

            unchecked
            {
                hashCode = Constants.HashMultiplier * hashCode + RegisteredType.GetHashCode();
                hashCode = Constants.HashMultiplier * hashCode + Name.GetHashCode();
            }

            return(hashCode);
        }
示例#11
0
        private object ResolveAndCreate(RegisteredType registered)
        {
            ConstructorInfo dependentCtor = GetConstructorInfo(registered.ObjectType);

            if (dependentCtor == null)
            {
                // use the default constructor to create
                return(CreationService.Instance.GetInstance(registered));
            }

            //we got some parameter(types)s that need to be created
            return(CreateCtor(registered, dependentCtor));
        }
 private void UpdateContainerEntry(Type type, RegisteredType entrySettings)
 {
     lock (_settings)
     {
         if (_settings.ContainsKey(type))
         {
             // Replace
             _settings[type] = entrySettings;
         }
         else
         {
             // Add
             _settings.Add(type, entrySettings);
         }
     }
 }
示例#13
0
        /// <summary>
        /// Register a custom type into the interpreter( for calling c# from the language ).
        /// </summary>
        /// <param name="type"></param>
        /// <param name="creator"></param>
        public void Register(Type type, Func<object> creator)
        {
            bool isBasicType = false;
            if( type == typeof(DateTime) )
            {
                isBasicType = true;
                creator = () => new DateTime(DateTime.Now.Ticks);
            }

            var registeredType = new RegisteredType() 
            { 
                IsBasicType = isBasicType, DataType = type, Creator = creator,
                Name = type.Name, FullName = type.FullName
            };
            _types[type.Name] = registeredType;
            _types[type.FullName] = registeredType;
        }
        public IServiceContainer Add(Type serviceType, Func <IServiceFactory, object> factory, Lifetime lifetime)
        {
            if (serviceType is null)
            {
                throw new ArgumentNullException(nameof(serviceType));
            }
            if (factory is null)
            {
                throw new ArgumentNullException(nameof(factory));
            }

            var settings = new RegisteredType(lifetime, factory);

            UpdateContainerEntry(serviceType, settings);

            return(this);
        }
        /// <summary>
        /// Register a custom type into the interpreter( for calling c# from the language ).
        /// </summary>
        /// <param name="type"></param>
        /// <param name="creator"></param>
        public void Register(Type type, Func <object> creator)
        {
            bool isBasicType = false;

            if (type == typeof(DateTime))
            {
                isBasicType = true;
                creator     = () => new DateTime(DateTime.Now.Ticks);
            }

            var registeredType = new RegisteredType()
            {
                IsBasicType = isBasicType, DataType = type, Creator = creator,
                Name        = type.Name, FullName = type.FullName
            };

            _types[type.Name]     = registeredType;
            _types[type.FullName] = registeredType;
        }
示例#16
0
        //creates ctor and it dendencies if needed.
        private object CreateCtor(RegisteredType registered, ConstructorInfo dependentCtor)
        {
            // We found a constructor with dependency attribute
            ParameterInfo[] parameters = dependentCtor.GetParameters();
            if (parameters.Length == 0)
            {
                // Futile dependency attribute, use the default constructor only
                return(CreationService.Instance.GetInstance(registered));
            }

            // valid dependency attribute, create the dependencies first and pass them to the constructor
            object[] arguments = new object[parameters.Length];
            for (int i = 0; i < parameters.Length; i++)
            {
                arguments[i] = Resolve(parameters[i].ParameterType);
            }

            return(CreationService.Instance.GetInstance(registered, arguments));
        }
        private object Resolve(RegisteredType registeredType, Type[] genericTypeArguments)
        {
            if (registeredType.HasCustomConstructor)
            {
                var instance = _instanceFactory.CreateInstance(this, registeredType.CustomConstructor);

                return(instance);
            }
            else
            {
                Type implementation = registeredType.ImplementationType;
                if (genericTypeArguments.Length > 0)
                {
                    implementation = implementation.MakeGenericType(genericTypeArguments);
                }

                var instance = _instanceFactory.CreateInstance(this, implementation);

                return(instance);
            }
        }
        public IServiceContainer Add(Type serviceType, Type implementationType, Lifetime lifetime)
        {
            if (serviceType is null)
            {
                throw new ArgumentNullException(nameof(serviceType));
            }
            if (implementationType is null)
            {
                throw new ArgumentNullException(nameof(implementationType));
            }
            if (!serviceType.ContainsGenericParameters && !serviceType.IsAssignableFrom(implementationType))
            {
                throw new ArgumentException($"{nameof(implementationType)} is not assignable from {nameof(serviceType)}");
            }

            var settings = new RegisteredType(lifetime, implementationType);

            UpdateContainerEntry(serviceType, settings);

            return(this);
        }
示例#19
0
        private Type GetLifetimeManagerType(IPolicyList policies)
        {
            var key      = new NamedTypeBuildKey(RegisteredType, Name);
            var lifetime = policies.Get <ILifetimePolicy>(key);

            if (lifetime != null)
            {
                return(lifetime.GetType());
            }

            if (RegisteredType.GetTypeInfo().IsGenericType)
            {
                var genericKey      = new NamedTypeBuildKey(RegisteredType.GetGenericTypeDefinition(), Name);
                var lifetimeFactory = policies.Get <ILifetimeFactoryPolicy>(genericKey);
                if (lifetimeFactory != null)
                {
                    return(lifetimeFactory.LifetimeType);
                }
            }

            return(typeof(TransientLifetimeManager));
        }
示例#20
0
        //Using the container(interface) as the key, adds type to register and container to the dictionary
        private void Register(Type interfaceType, Type implType, LifeCycle lifeCycle)
        {
            if (interfaceType == null)
            {
                throw new ArgumentNullException("interfaceType Cant be null");
            }
            if (implType == null)
            {
                throw new ArgumentNullException("implType cant be null");
            }
            if (!interfaceType.IsAssignableFrom(implType))
            {
                throw new ArgumentException("implType");
            }

            if (_instanceRegistry.ContainsKey(interfaceType))
            {
                _instanceRegistry[interfaceType].Add(new RegisteredType
                {
                    LifeCycle  = lifeCycle,
                    ObjectType = implType
                });
            }
            else
            {
                var registeredType = new RegisteredType
                {
                    LifeCycle  = lifeCycle,
                    ObjectType = implType
                };

                _instanceRegistry.Add(interfaceType, new HashSet <RegisteredType> {
                    registeredType
                });
            }
        }
示例#21
0
        private object[] ResolveConstructorParameters(RegisteredType registeredObj)
        {
            var constructorInfo = registeredObj.ConcreteType.GetConstructors().First();

            return(constructorInfo.GetParameters().Select(parameter => ResolveObject(parameter.ParameterType)).ToArray());
        }
示例#22
0
        void OutputType(RegisteredType t, bool full)
        {
            if (_emittedTypes != null)
            {
                if (!t.Type.IsValueType)
                {
                    var baseType = t.Type.BaseType;
                    if (baseType != null)
                    {
                        var baseRegistration = _compilation.GetRegisteredType(baseType);
                        if (!_emittedTypes.Contains(baseRegistration))
                        {
                            OutputType(baseRegistration, full);
                        }
                    }
                }

                foreach (var field in t.Type.GetFields())
                {
                    if (!_compilation.GetRegisteredField(field).IncludedInCompilation)
                    {
                        continue;
                    }

                    var fieldType = field.FieldType;
                    if (fieldType.IsValueType && !fieldType.IsPrimitive && !field.IsStatic)
                    {
                        var fieldTypeRegistration = _compilation.GetRegisteredType(fieldType);
                        if (!_emittedTypes.Contains(fieldTypeRegistration))
                        {
                            OutputType(fieldTypeRegistration, full);
                        }
                    }
                }

                _emittedTypes.Add(t);
            }

            string mangledName = GetCppTypeName(t.Type);

            int nesting = 0;
            int current = 0;

            for (;;)
            {
                int sep = mangledName.IndexOf("::", current);
                if (sep < 0)
                {
                    break;
                }

                Out.Write("namespace " + mangledName.Substring(current, sep - current) + " { ");
                current = sep + 2;

                nesting++;
            }

            if (full)
            {
                Out.Write("class " + mangledName.Substring(current));
                if (!t.Type.IsValueType)
                {
                    var baseType = t.Type.BaseType;
                    if (baseType != null)
                    {
                        Out.Write(" : public " + GetCppTypeName(baseType));
                    }
                }
                Out.WriteLine(" { public:");
                if (t.IncludedInCompilation)
                {
                    Out.WriteLine("static MethodTable * __getMethodTable();");
                }
                if (t.VirtualSlots != null)
                {
                    int baseSlots = 0;
                    var baseType  = t.Type.BaseType;
                    while (baseType != null)
                    {
                        var baseReg = _compilation.GetRegisteredType(baseType);
                        if (baseReg.VirtualSlots != null)
                        {
                            baseSlots += baseReg.VirtualSlots.Count;
                        }
                        baseType = baseType.BaseType;
                    }

                    for (int slot = 0; slot < t.VirtualSlots.Count; slot++)
                    {
                        MethodDesc virtualMethod = t.VirtualSlots[slot];
                        Out.WriteLine(GetCodeForVirtualMethod(virtualMethod, baseSlots + slot));
                    }
                }
                if (t.Type.IsDelegate)
                {
                    Out.WriteLine(GetCodeForDelegate(t.Type));
                }
                foreach (var field in t.Type.GetFields())
                {
                    if (!_compilation.GetRegisteredField(field).IncludedInCompilation)
                    {
                        continue;
                    }
                    if (field.IsStatic)
                    {
                        TypeDesc      fieldType = field.FieldType;
                        StringBuilder builder;
                        if (!fieldType.IsValueType)
                        {
                            _gcStatics.Append(GetCppSignatureTypeName(fieldType));
                            builder = _gcStatics;
                        }
                        else
                        {
                            // TODO: Valuetype statics with GC references
                            _statics.Append(GetCppSignatureTypeName(fieldType));
                            builder = _statics;
                        }
                        builder.AppendLine(" " + GetCppStaticFieldName(field) + ";");
                    }
                    else
                    {
                        Out.WriteLine(GetCppSignatureTypeName(field.FieldType) + " " + GetCppFieldName(field) + ";");
                    }
                }
                if (t.Type.GetMethod(".cctor", null) != null)
                {
                    _statics.AppendLine("bool __cctor_" + GetCppTypeName(t.Type).Replace("::", "__") + ";");
                }

                if (t.Methods != null)
                {
                    foreach (var m in t.Methods)
                    {
                        if (m.IncludedInCompilation)
                        {
                            OutputMethod(m);
                        }
                    }
                }
                Out.Write("};");
            }
            else
            {
                Out.Write("class " + mangledName.Substring(current) + ";");
            }

            while (nesting > 0)
            {
                Out.Write(" };");
                nesting--;
            }
            Out.WriteLine();
        }
示例#23
0
 public static RegisteredType AsSingleton(this RegisteredType registeredType)
 {
     registeredType.IsSingleton = true;
     return(registeredType);
 }
示例#24
0
 public static RegisteredType InstancePerRequest(this RegisteredType registeredType)
 {
     registeredType.IsSingleton = false;
     return(registeredType);
 }
示例#25
0
        private void OutputType(RegisteredType t, bool full)
        {
            if (_emittedTypes != null)
            {
                if (!t.Type.IsValueType)
                {
                    var baseType = t.Type.BaseType;
                    if (baseType != null)
                    {
                        var baseRegistration = _compilation.GetRegisteredType(baseType);
                        if (!_emittedTypes.Contains(baseRegistration))
                        {
                            OutputType(baseRegistration, full);
                        }
                    }
                }

                foreach (var field in t.Type.GetFields())
                {
                    if (!_compilation.GetRegisteredField(field).IncludedInCompilation)
                        continue;

                    var fieldType = field.FieldType;
                    if (fieldType.IsValueType && !fieldType.IsPrimitive && !field.IsStatic)
                    {
                        var fieldTypeRegistration = _compilation.GetRegisteredType(fieldType);
                        if (!_emittedTypes.Contains(fieldTypeRegistration))
                        {
                            OutputType(fieldTypeRegistration, full);
                        }
                    }
                }

                _emittedTypes.Add(t);
            }

            string mangledName = GetCppTypeName(t.Type);

            int nesting = 0;
            int current = 0;
            for (;;)
            {
                int sep = mangledName.IndexOf("::", current);
                if (sep < 0)
                    break;

                Out.Write("namespace " + mangledName.Substring(current, sep - current) + " { ");
                current = sep + 2;

                nesting++;
            }

            if (full)
            {
                Out.Write("class " + mangledName.Substring(current));
                if (!t.Type.IsValueType)
                {
                    var baseType = t.Type.BaseType;
                    if (baseType != null)
                    {
                        Out.Write(" : public " + GetCppTypeName(baseType));
                    }
                }
                Out.WriteLine(" { public:");
                if (t.IncludedInCompilation)
                {
                    Out.WriteLine("static MethodTable * __getMethodTable();");
                }
                if (t.VirtualSlots != null)
                {
                    int baseSlots = 0;
                    var baseType = t.Type.BaseType;
                    while (baseType != null)
                    {
                        var baseReg = _compilation.GetRegisteredType(baseType);
                        if (baseReg.VirtualSlots != null)
                            baseSlots += baseReg.VirtualSlots.Count;
                        baseType = baseType.BaseType;
                    }

                    for (int slot = 0; slot < t.VirtualSlots.Count; slot++)
                    {
                        MethodDesc virtualMethod = t.VirtualSlots[slot];
                        Out.WriteLine(GetCodeForVirtualMethod(virtualMethod, baseSlots + slot));
                    }
                }
                if (t.Type.IsDelegate)
                {
                    Out.WriteLine(GetCodeForDelegate(t.Type));
                }
                foreach (var field in t.Type.GetFields())
                {
                    if (!_compilation.GetRegisteredField(field).IncludedInCompilation)
                        continue;
                    if (field.IsStatic)
                    {
                        TypeDesc fieldType = field.FieldType;
                        StringBuilder builder;
                        if (!fieldType.IsValueType)
                        {
                            _gcStatics.Append(GetCppSignatureTypeName(fieldType));
                            builder = _gcStatics;
                        }
                        else
                        {
                            // TODO: Valuetype statics with GC references
                            _statics.Append(GetCppSignatureTypeName(fieldType));
                            builder = _statics;
                        }
                        builder.AppendLine(" " + GetCppStaticFieldName(field) + ";");
                    }
                    else
                    {
                        Out.WriteLine(GetCppSignatureTypeName(field.FieldType) + " " + GetCppFieldName(field) + ";");
                    }
                }
                if (t.Type.GetMethod(".cctor", null) != null)
                {
                    _statics.AppendLine("bool __cctor_" + GetCppTypeName(t.Type).Replace("::", "__") + ";");
                }

                if (t.Methods != null)
                {
                    foreach (var m in t.Methods)
                    {
                        if (m.IncludedInCompilation)
                            OutputMethod(m);
                    }
                }
                Out.Write("};");
            }
            else
            {
                Out.Write("class " + mangledName.Substring(current) + ";");
            }

            while (nesting > 0)
            {
                Out.Write(" };");
                nesting--;
            }
            Out.WriteLine();
        }
示例#26
0
 private object CreateInstance(RegisteredType registeredObj)
 {
     return(registeredObj.SingletonInstance ?? registeredObj.CreateInstance(ResolveConstructorParameters(registeredObj)));
 }
示例#27
0
        internal RegisteredType GetRegisteredType(TypeDesc type)
        {
            RegisteredType existingRegistration;
            if (_registeredTypes.TryGetValue(type, out existingRegistration))
                return existingRegistration;

            RegisteredType registration = new RegisteredType() { Type = type };
            _registeredTypes.Add(type, registration);

            // Register all base types too
            var baseType = type.BaseType;
            if (baseType != null)
                GetRegisteredType(baseType);

            return registration;
        }