예제 #1
0
        public static DependencyLifetime DefineLifetime(this IDependencyEngine engine, Type implementation)
        {
            var constructor = ReflectionUtils.GetConstructor(implementation);

            if (constructor == null)
            {
                throw Error.DefaultConstructorNotFound(implementation);
            }

            var parameters = constructor.GetParameters();

            var dependencies = new LocalList <DependencyLifetime>();

            foreach (var parameter in parameters)
            {
                var required   = !parameter.HasDefaultValue;
                var dependency = required
                    ? engine.GetRequiredDependency(parameter.ParameterType)
                    : engine.GetDependency(parameter.ParameterType);

                if (dependency != null)
                {
                    dependencies.Add(dependency.Lifetime);
                }
            }

            return(dependencies.DefineLifetime());
        }
예제 #2
0
        private Func <IServiceProvider, object> CreateBuilder(IServiceProvider services)
        {
            var servicesArgument = Expression.Parameter(typeof(IServiceProvider), "services");

            var constructorParameters = _constructor.GetParameters();
            var parameters            = new Expression[constructorParameters.Length];

            for (var i = constructorParameters.Length - 1; i >= 0; i--)
            {
                var parameter     = constructorParameters[i];
                var parameterType = parameter.ParameterType;
                var required      = !parameter.HasDefaultValue;

                var parameterDependency = required
                    ? _dependencyEngine.GetRequiredDependency(parameterType)
                    : _dependencyEngine.GetDependency(parameterType);

                parameters[i] = parameterDependency == null
                    ? Expression.Default(parameterType)
                    : BuildParameter(parameterDependency, parameterType, services, servicesArgument);
            }

            var body = Expression.New(_constructor, parameters);

            return(Expression.Lambda <Func <IServiceProvider, object> >(body, servicesArgument).Compile());
        }
예제 #3
0
        protected void EnsureValidDependenciesLifetime(
            ConstructorInfo constructor,
            DependencyLifetime dependedLifetime, IDependencyEngine engine)
        {
            var parameters = constructor.GetParameters();

            foreach (var parameter in parameters)
            {
                var dependencyType = parameter.ParameterType;
                var dependency     = parameter.IsOptional
                    ? engine.GetDependency(dependencyType)
                    : engine.GetRequiredDependency(dependencyType);

                if (dependency == null)
                {
                    continue;
                }

                var dependencyLifetime = dependency.Lifetime;
                if (dependedLifetime == DependencyLifetime.Singleton && dependencyLifetime == DependencyLifetime.Scoped)
                {
                    throw Error.InconsistentLifetime(Implementation, dependedLifetime, dependencyType, dependencyLifetime);
                }
            }
        }
예제 #4
0
        public object?GetService(Type contract)
        {
            EnsureNotDisposed();

            if (contract == typeof(IServiceProvider))
            {
                return(this);
            }

            lock (_providerLock)
            {
                if (_scopeInstances.TryGetValue(contract, out var exists))
                {
                    return(exists);
                }

                var dependency = _engine.GetDependency(contract);

                if (dependency == null)
                {
                    return(null);
                }

                var instance = dependency.GetInstance(contract, this);

                if (dependency.Lifetime == DependencyLifetime.Scoped)
                {
                    _scopeInstances.Add(contract, instance);
                }

                return(instance);
            }
        }
예제 #5
0
        public IDependency BuildDependency(Type contract, IDependencyEngine engine)
        {
            var constructor = ReflectionUtils.GetConstructor(contract);
            var parameters  = constructor.GetParameters();

            var dependencies = new LocalList <IDependency>();

            foreach (var parameter in parameters)
            {
                var required   = !parameter.HasDefaultValue;
                var dependency = engine.GetDependency(parameter.ParameterType, required);
                dependencies.Add(dependency);
            }

            var lifetime = dependencies.DefineLifetime();
            var resolver = DependencyResolver.Build(lifetime, contract, engine);

            return(Dependency.Build(lifetime, new[] { contract }, resolver));
        }
예제 #6
0
        private Func<IDependencyScope, object> CreateBuilder(IDependencyScope scope)
        {
            var constructorParameters = _constructor.GetParameters();

            var argument = Expression.Parameter(typeof(IDependencyScope), "scope");
            var parameters = new Expression[constructorParameters.Length];
            for (var i = 0; i < constructorParameters.Length; i++)
            {
                var parameter = constructorParameters[i];
                var parameterType = parameter.ParameterType;
                var required = !parameter.HasDefaultValue;

                var parameterDependency = _dependencyEngine.GetDependency(parameterType, required);
                parameters[i] = BuildParameter(parameterDependency, parameterType, argument, scope);
            }

            var body = Expression.New(_constructor, parameters);
            var result = Expression.Lambda<Func<IDependencyScope, object>>(body, argument).Compile();

            return result;
        }