/// <summary>
 /// Build factory from original factory and reuse type
 /// </summary>
 /// <param name="container">IoC container</param>
 /// <param name="originalFactory">Original factory</param>
 /// <param name="reuseType">Reuse type</param>
 /// <returns></returns>
 public static Func <object> BuildFactory(
     this IContainer container, Func <object> originalFactory, ReuseType reuseType)
 {
     if (reuseType == ReuseType.Transient)
     {
         // Transient
         return(originalFactory);
     }
     else if (reuseType == ReuseType.Singleton)
     {
         // Singleton
         object value     = null;
         object valueLock = new object();
         return(() => {
             if (value != null)
             {
                 return value;
             }
             lock (valueLock) {
                 if (value != null)
                 {
                     return value;                             // double check
                 }
                 value = originalFactory();
                 return value;
             }
         });
     }
     else
     {
         throw new NotSupportedException(string.Format("unsupported reuse type {0}", reuseType));
     }
 }
Exemple #2
0
 /// <summary>
 /// Initialize<br/>
 /// 初始化<br/>
 /// </summary>
 public ContainerFactoryData(
     ContainerFactoryDelegate factoryFunc,
     ReuseType reuseType,
     Type implementationTypeHint)
 {
     _factoryFunc             = factoryFunc;
     _factoryLock             = new object();
     _isGenericTypeDefinition = implementationTypeHint.IsGenericTypeDefinition;
     if (reuseType == ReuseType.Singleton)
     {
         if (_isGenericTypeDefinition)
         {
             _singletonInstance = new ConcurrentDictionary <string, object>();
         }
     }
     else if (reuseType == ReuseType.Scoped)
     {
         _scopedInstance = new AsyncLocal <object>();
     }
     else if (reuseType != ReuseType.Transient)
     {
         throw new NotSupportedException(string.Format(
                                             "Unsupported reuse type {0}", ReuseType));
     }
     ReuseType = reuseType;
     ImplementationTypeHint = implementationTypeHint;
 }
Exemple #3
0
        /// <summary>
        /// Register implementation type with service types and service key
        /// </summary>
        public void RegisterMany(
            IList <Type> serviceTypes, Type implementationType, ReuseType reuseType, object serviceKey)
        {
            var factory = this.BuildFactory(implementationType, reuseType);

            RegisterFactoryMany(serviceTypes, factory, serviceKey);
        }
Exemple #4
0
        /// <summary>
        /// Register implementation type with service types and service key
        /// Service types are obtain from base types and interfaces
        /// </summary>
        public void RegisterMany(Type implementationType,
                                 ReuseType reuseType, object serviceKey, bool nonPublicServiceTypes)
        {
            var serviceTypes = GetImplementedServiceTypes(
                implementationType, nonPublicServiceTypes).ToList();

            RegisterMany(serviceTypes, implementationType, reuseType, serviceKey);
        }
Exemple #5
0
        /// <summary>
        /// Register implementation type with service type and service key<br/>
        /// 根据服务类型和服务键注册实现类型<br/>
        /// </summary>
        public void Register(
            Type serviceType, Type implementationType, ReuseType reuseType, object serviceKey)
        {
            var factory     = this.BuildFactory(implementationType, reuseType);
            var factoryData = new ContainerFactoryData(factory, implementationType);

            RegisterFactory(serviceType, factoryData, serviceKey);
        }
 public Reuse(bool isDirect, ReuseType type, string name, Class fromClass, string fromReference)
 {
     _isDirect      = isDirect;
     _type          = type;
     _name          = name;
     _fromClass     = fromClass;
     _fromReference = fromReference;
 }
Exemple #7
0
        /// <summary>
        /// Register delegate with service type and service key<br/>
        /// 根据服务类型和服务键注册工厂函数<br/>
        /// </summary>
        public void RegisterDelegate(
            Type serviceType, Func <object> factory, ReuseType reuseType, object serviceKey)
        {
            factory = this.BuildFactory(factory, reuseType);
            // We can't known what type will be returned, the hint type will be service type
            var factoryData = new ContainerFactoryData(factory, serviceType);

            RegisterFactory(serviceType, factoryData, serviceKey);
        }
Exemple #8
0
        /// <summary>
        /// Register implementation type with service types and service key<br/>
        /// Service types are obtain from base types and interfaces<br/>
        /// 根据多个服务类型和服务键注册实现类型<br/>
        /// 服务类型是实现类型的基类和接口<br/>
        /// </summary>
        public void RegisterMany(Type implementationType,
                                 ReuseType reuseType = ReuseType.Transient,
                                 object serviceKey   = null, bool nonPublicServiceTypes = false)
        {
            var serviceTypes = GetImplementedServiceTypes(
                implementationType, nonPublicServiceTypes).ToList();

            RegisterMany(serviceTypes, implementationType, reuseType, serviceKey);
        }
Exemple #9
0
 /// <summary>
 /// Register implementation type to container<br/>
 /// 注册实现类型到容器<br/>
 /// </summary>
 public override void RegisterToContainer(IContainer container, Type type, ReuseType reuseType)
 {
     // Apply clear exist
     if (ClearExists)
     {
         container.Unregister(ServiceType, ContractKey);
     }
     // Register to container
     container.Register(ServiceType, type, reuseType, ContractKey);
 }
Exemple #10
0
 /// <summary>
 /// Register implementation type with service type and service key<br/>
 /// 根据服务类型和服务键注册实现类型<br/>
 /// </summary>
 public void Register(
     Type serviceType, Type implementationType, ReuseType reuseType, object serviceKey)
 {
     var factoryData = FactoryDataCache.GetOrAdd(
         Pair.Create(implementationType, reuseType),
         pair => {
         this.NonGenericBuildAndWrapFactory(
             pair.First, pair.Second, out var genericFactory, out var objectFactory);
         return(new ContainerFactoryData(genericFactory, objectFactory, pair.First));
     });
Exemple #11
0
        /// <summary>
        /// Register implementation type with service types and service key<br/>
        /// 根据多个服务类型和服务键注册实现类型<br/>
        /// </summary>
        public void RegisterMany(
            IList <Type> serviceTypes, Type implementationType,
            ReuseType reuseType = ReuseType.Transient, object serviceKey = null)
        {
            var factoryData = new ContainerFactoryData(
                ContainerFactoryBuilder.BuildFactory(implementationType),
                reuseType,
                implementationType);

            RegisterFactoryMany(serviceTypes, factoryData, serviceKey);
        }
Exemple #12
0
		private void OnRequestTest(
			Action action, ReuseType reuseType = ReuseType.Transient) {
			using (Application.OverrideIoc()) {
				Application.Ioc.Unregister<ControllerManager>();
				Application.Ioc.RegisterMany<ControllerManager>(ReuseType.Singleton);
				Application.Ioc.Unregister<IController>();
				Application.Ioc.Register<IController, TestController>(reuseType);
				var controllerManager = Application.Ioc.Resolve<ControllerManager>();
				controllerManager.Initialize();
				action();
			}
		}
Exemple #13
0
        /// <summary>
        /// Register delegate with service type and service key<br/>
        /// 根据服务类型和服务键注册工厂函数<br/>
        /// </summary>
        public void RegisterDelegate(
            Type serviceType, ContainerFactoryDelegate factory,
            ReuseType reuseType = ReuseType.Transient, object serviceKey = null)
        {
            // Since we can't figure out what type will returned from factory,
            // the implementation hint type will be the service type
            var factoryData = new ContainerFactoryData(
                factory,
                reuseType,
                serviceType);

            RegisterFactory(serviceType, factoryData, serviceKey);
        }
        /// <summary>
        /// Build factory from original factory and reuse type<br/>
        /// Return genericFactory for Func&lt;T&gt; and objectFactory for Func&lt;object&gt;<br/>
        /// 根据原工厂函数和重用类型构建新的工厂函数<br/>
        /// 返回Func&lt;T&gt;类型的genericFactory和Func&lt;object&gt;类型的objectFactory<br/>
        /// </summary>
        /// <seealso cref="GenericWrapFactory{T}(IContainer, Func{T}, ReuseType)"/>
        public static void NonGenericWrapFactory(
            this IContainer container, Type type, Func <object> originalFactory, ReuseType reuseType,
            out object genericFactory, out Func <object> objectFactory)
        {
            if (type.IsGenericTypeDefinition)
            {
                throw new NotSupportedException("Register generic definition with factory is unsupported");
            }
            var makeObjectFactory  = ReflectionUtils.MakeInvoker(GenericWrapFactoryMethod, typeof(object));
            var makeGenericFactory = ReflectionUtils.MakeInvoker(ToGenericFactoryMethod, type);

            objectFactory  = (Func <object>)makeObjectFactory(null, new object[] { container, originalFactory, reuseType });
            genericFactory = makeGenericFactory(null, new object[] { objectFactory });
        }
Exemple #15
0
        /// <summary>
        /// Build factory from type and reuse type<br/>
        /// 根据类型和重用类型构建工厂函数<br/>
        /// </summary>
        /// <param name="container">IoC container</param>
        /// <param name="type">The type</param>
        /// <param name="reuseType">Reuse type</param>
        /// <returns></returns>
        /// <example>
        /// <code language="cs">
        /// class TestData { }
        ///
        /// class TestInjection {
        ///     public TestData Data { get; set; }
        ///     public TestInjection(TestData data) { Data = data; }
        /// }
        ///
        /// IContainer container = new Container();
        /// container.RegisterMany&lt;TestData&gt;();
        /// var factory = container.BuildFactory(typeof(TestInjection), ReuseType.Transient);
        /// var testInjection = (TestInjection)factory();
        /// </code>
        /// </example>
        public static Func <object> BuildFactory(
            this IContainer container, Type type, ReuseType reuseType)
        {
            var typeFactor = TypeFactorysCache.GetOrAdd(type, t => {
                // Support constructor dependency injection
                // First detect Inject attribute, then use the constructor that have most parameters
                var argumentExpressions = new List <Expression>();
                var constructors        = t.GetConstructors();
                var constructor         = constructors.FirstOrDefault(
                    c => c.GetAttribute <InjectAttribute>() != null);
                if (constructor == null)
                {
                    constructor = constructors
                                  .Where(c => c.IsPublic)
                                  .OrderByDescending(c => c.GetParameters().Length)
                                  .FirstOrDefault();
                }
                if (constructor == null)
                {
                    throw new ArgumentException(
                        $"Type {type} should have atleast one public constructor");
                }
                foreach (var parameter in constructor.GetParameters())
                {
                    var parameterType     = parameter.ParameterType;
                    var parameterTypeInfo = parameterType.GetTypeInfo();
                    if (parameterTypeInfo.IsGenericType &&
                        parameterTypeInfo.GetGenericTypeDefinition() == typeof(IEnumerable <>))
                    {
                        argumentExpressions.Add(Expression.Call(
                                                    Expression.Constant(container), nameof(IContainer.ResolveMany),
                                                    parameterTypeInfo.GetGenericArguments(),
                                                    Expression.Constant(null)));
                    }
                    else
                    {
                        argumentExpressions.Add(Expression.Call(
                                                    Expression.Constant(container), nameof(IContainer.Resolve),
                                                    new[] { parameterType },
                                                    Expression.Constant(IfUnresolved.ReturnDefault),
                                                    Expression.Constant(null)));
                    }
                }
                var newExpression = Expression.New(constructor, argumentExpressions);
                return(Expression.Lambda <Func <object> >(newExpression).Compile());
            });

            return(container.BuildFactory(typeFactor, reuseType));
        }
        /// <summary>
        /// Build factory from type and wrap it with reuse type<br/>
        /// Please cache result from this method for better performance<br/>
        /// 根据类型构建工厂函数, 并根据重用类型包装<br/>
        /// 请缓存这个函数的结果, 以得到更好的性能<br/>
        /// </summary>
        public static Func <T> GenericBuildAndWrapFactory <T>(
            this IContainer container, ReuseType reuseType)
        {
            var type = typeof(T);
            // Support constructor dependency injection
            // First: use constructor marked with InjectAttribute
            var constructors = type.GetConstructors();
            var constructor  = constructors
                               .Where(c => c.GetAttribute <InjectAttribute>() != null).SingleOrDefaultNotThrow();

            // Second: use the only public constructor
            if (constructor == null)
            {
                constructor = constructors.Where(c => c.IsPublic).SingleOrDefaultNotThrow();
            }
            // Third: use runtime resolver
            Func <T> factory;

            if (constructor != null)
            {
                factory = container.GenericBuildFactoryFromConstructor <T>(constructor);
            }
            else
            {
                factory = () => {
                    var resolver = container.Resolve <IMultiConstructorResolver>(IfUnresolved.ReturnDefault);
                    if (resolver == null)
                    {
                        throw new ArgumentException(
                                  $"Type {type} have multi constructor and no one is marked with [Inject]," +
                                  "please mark one with [Inject] or provide IMultiConstructorResolver");
                    }
                    else
                    {
                        return(resolver.Resolve <T>());
                    }
                };
            }
            // Wrap factory
            return(container.GenericWrapFactory(factory, reuseType));
        }
Exemple #17
0
        /// <summary>
        /// Build factory from type and reuse type
        /// </summary>
        /// <param name="container">IoC container</param>
        /// <param name="type">The type</param>
        /// <param name="reuseType">Reuse type</param>
        /// <returns></returns>
        public static Func <object> BuildFactory(
            this IContainer container, Type type, ReuseType reuseType)
        {
            var typeFactor = TypeFactorysCache.GetOrAdd(type, t => {
                // Support constructor dependency injection
                var argumentExpressions = new List <Expression>();
                var constructor         = t.GetConstructors().Where(c => c.IsPublic).FirstOrDefault();
                if (constructor == null)
                {
                    throw new ArgumentException(
                        $"Type {type} should have atleast one public constructor");
                }
                foreach (var parameter in constructor.GetParameters())
                {
                    var parameterType     = parameter.ParameterType;
                    var parameterTypeInfo = parameterType.GetTypeInfo();
                    if (parameterTypeInfo.IsGenericType &&
                        parameterTypeInfo.GetGenericTypeDefinition() == typeof(IEnumerable <>))
                    {
                        argumentExpressions.Add(Expression.Call(
                                                    Expression.Constant(container), "ResolveMany",
                                                    parameterTypeInfo.GetGenericArguments(),
                                                    Expression.Constant(null)));
                    }
                    else
                    {
                        argumentExpressions.Add(Expression.Call(
                                                    Expression.Constant(container), "Resolve",
                                                    new[] { parameterType },
                                                    Expression.Constant(IfUnresolved.Throw),
                                                    Expression.Constant(null)));
                    }
                }
                var newExpression = Expression.New(constructor, argumentExpressions);
                return(Expression.Lambda <Func <object> >(newExpression).Compile());
            });

            return(container.BuildFactory(typeFactor, reuseType));
        }
        /// <summary>
        /// Register implementation type to container<br/>
        /// 注册实现类型到容器<br/>
        /// </summary>
        public override void RegisterToContainer(IContainer container, Type type, ReuseType reuseType)
        {
            var serviceTypes = Container.GetImplementedServiceTypes(type, NonPublic);

            // Apply except types
            if (Except != null && Except.Any())
            {
                serviceTypes = serviceTypes.Where(t => !Except.Contains(t));
            }
            var serviceTypesArray = serviceTypes.ToList();

            // Apply clear exist
            if (ClearExists)
            {
                foreach (var serviceType in serviceTypesArray)
                {
                    container.Unregister(serviceType, ContractKey);
                }
            }
            // Register to container
            container.RegisterMany(serviceTypesArray, type, reuseType, ContractKey);
        }
 /// <summary>
 /// Build factory from type and wrap it with reuse type<br/>
 /// Return genericFactory for Func&lt;T&gt; and objectFactory for Func&lt;object&gt;<br/>
 /// Please cache result from this method for better performance<br/>
 /// 根据类型和重用类型构建工厂函数<br/>
 /// 返回Func&lt;T&gt;类型的genericFactory和Func&lt;object&gt;类型的objectFactory<br/>
 /// 请缓存这个函数的结果, 以得到更好的性能<br/>
 /// </summary>
 public static void NonGenericBuildAndWrapFactory(
     this IContainer container, Type type, ReuseType reuseType,
     out object genericFactory, out Func <object> objectFactory)
 {
     if (type.IsGenericTypeDefinition)
     {
         // Register Implementation<T> to Service<T>
         var factoryCache   = new ConcurrentDictionary <Type, Func <object> >();
         var factoryFactory = new Func <Func <Type, object> >(() => {
             return(new Func <Type, object>(serviceType => {
                 var bindType = type.MakeGenericType(serviceType.GetGenericArguments());
                 var factory = factoryCache.GetOrAdd(serviceType, _ => {
                     var makeGenericFactory = ReflectionUtils.MakeInvoker(
                         GenericBuildAndWrapFactoryMethod, bindType);
                     var makeObjectFactory = ReflectionUtils.MakeInvoker(
                         ToObjectFactoryMethod, bindType);
                     var innerGenericFactory = makeGenericFactory(
                         null, new object[] { container, reuseType });
                     var innerObjectFactory = (Func <object>)makeObjectFactory(
                         null, new object[] { innerGenericFactory });
                     return innerObjectFactory;
                 });
                 return factory();
             }));
         });
         objectFactory  = factoryFactory;
         genericFactory = objectFactory;
     }
     else
     {
         // Normal case
         var makeGenericFactory = ReflectionUtils.MakeInvoker(GenericBuildAndWrapFactoryMethod, type);
         var makeObjectFactory  = ReflectionUtils.MakeInvoker(ToObjectFactoryMethod, type);
         genericFactory = makeGenericFactory(null, new object[] { container, reuseType });
         objectFactory  = (Func <object>)makeObjectFactory(null, new object[] { genericFactory });
     }
 }
Exemple #20
0
 /// <summary>
 /// Register delegate with service type and service key
 /// </summary>
 public void RegisterDelegate(
     Type serviceType, Func <object> factory, ReuseType reuseType, object serviceKey)
 {
     factory = this.BuildFactory(factory, reuseType);
     RegisterFactory(serviceType, factory, serviceKey);
 }
Exemple #21
0
 /// <summary>
 /// Register implementation type with service types and service key
 /// Service types are obtain from base types and interfaces
 /// </summary>
 public void RegisterMany <TImplementation>(
     ReuseType reuseType, object serviceKey, bool nonPublicServiceTypes)
 {
     RegisterMany(typeof(TImplementation), reuseType, serviceKey, nonPublicServiceTypes);
 }
Exemple #22
0
 /// <summary>Specify the reuse type and the scope name.</summary>
 public ReuseAttribute(ReuseType reuseType, params object[] scopeNames)
 {
     ReuseType  = reuseType;
     ScopeNames = scopeNames;
 }
Exemple #23
0
 /// <summary>
 /// Register implementation type with service type and service key
 /// </summary>
 public void Register <TService, TImplementation>(ReuseType reuseType, object serviceKey)
 {
     Register(typeof(TService), typeof(TImplementation), reuseType, serviceKey);
 }
Exemple #24
0
 /// <summary>Create attribute with specified type implementing reuse.</summary>
 /// <param name="reuseType">Supported reuse type.</param>
 /// <param name="scopeName">(optional) Name is valid only for Current Scope Reuse and will be ignored by the rest of reuse types.</param>
 public ReuseAttribute(ReuseType reuseType, string scopeName = null)
 {
     ReuseType = reuseType;
     ScopeName = scopeName;
 }
Exemple #25
0
 /// <summary>
 /// Register implementation type with service types and service key<br/>
 /// Service types are obtain from base types and interfaces<br/>
 /// 根据多个服务类型和服务键注册实现类型<br/>
 /// 服务类型是实现类型的基类和接口<br/>
 /// </summary>
 public void RegisterMany <TImplementation>(
     ReuseType reuseType = ReuseType.Transient,
     object serviceKey   = null, bool nonPublicServiceTypes = false)
 {
     RegisterMany(typeof(TImplementation), reuseType, serviceKey, nonPublicServiceTypes);
 }
Exemple #26
0
 /// <summary>
 /// Register delegate with service type and service key
 /// </summary>
 public void RegisterDelegate <TService>(
     Func <TService> factory, ReuseType reuseType, object serviceKey)
 {
     RegisterDelegate(typeof(TService), () => factory(), reuseType, serviceKey);
 }
Exemple #27
0
 /// <summary>
 /// Initialize<br/>
 /// 初始化<br/>
 /// </summary>
 /// <param name="reuseType">Reuse type</param>
 public ReuseAttribute(ReuseType reuseType)
 {
     ReuseType = reuseType;
 }
Exemple #28
0
 /// <summary>
 /// Register delegate with service type and service key<br/>
 /// 根据服务类型和服务键注册工厂函数<br/>
 /// </summary>
 public void RegisterDelegate(
     Type serviceType, Func <object> factory,
     ReuseType reuseType = ReuseType.Transient, object serviceKey = null)
 {
     RegisterDelegate(serviceType, (c, s) => factory(), reuseType, serviceKey);
 }
 /// <summary>
 /// Register implementation type to container<br/>
 /// 注册实现类型到容器<br/>
 /// </summary>
 /// <param name="container">Container</param>
 /// <param name="type">Implementation type</param>
 /// <param name="reuseType">Reuse type</param>
 public abstract void RegisterToContainer(IContainer container, Type type, ReuseType reuseType);
 /// <summary>
 /// Wrap factory with reuse type<br/>
 /// 根据重用类型包装工厂函数<br/>
 /// </summary>
 public static Func <T> GenericWrapFactory <T>(
     this IContainer container, Func <T> originalFactory, ReuseType reuseType)
 {
     if (reuseType == ReuseType.Transient)
     {
         // Transient
         return(originalFactory);
     }
     else if (reuseType == ReuseType.Singleton)
     {
         // Singleton
         var value        = default(T);
         var valueCreated = false;
         var valueLock    = new object();
         return(() => {
             if (valueCreated)
             {
                 return value;
             }
             lock (valueLock) {
                 if (valueCreated)
                 {
                     return value;                             // double check
                 }
                 value = originalFactory();
                 Interlocked.MemoryBarrier();
                 valueCreated = true;
                 return value;
             }
         });
     }
     else if (reuseType == ReuseType.Scoped)
     {
         // Scoped
         var value     = new AsyncLocal <Pair <bool, T> >();
         var valueLock = new object();
         return(() => {
             var pair = value.Value;
             if (pair.First)
             {
                 return pair.Second;
             }
             lock (valueLock) {
                 pair = value.Value;
                 if (pair.First)
                 {
                     return pair.Second;                             // double check
                 }
                 pair = Pair.Create(true, originalFactory());
                 if (pair.Second is IDisposable disposable)
                 {
                     container.DisposeWhenScopeFinished(disposable);
                 }
                 value.Value = pair;
                 return pair.Second;
             }
         });
     }
     else
     {
         throw new NotSupportedException(string.Format("unsupported reuse type {0}", reuseType));
     }
 }