/// <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)); } }
/// <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; }
/// <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); }
/// <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); }
/// <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; }
/// <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); }
/// <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); }
/// <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); }
/// <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)); });
/// <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); }
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(); } }
/// <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<T> and objectFactory for Func<object><br/> /// 根据原工厂函数和重用类型构建新的工厂函数<br/> /// 返回Func<T>类型的genericFactory和Func<object>类型的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 }); }
/// <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<TestData>(); /// 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)); }
/// <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<T> and objectFactory for Func<object><br/> /// Please cache result from this method for better performance<br/> /// 根据类型和重用类型构建工厂函数<br/> /// 返回Func<T>类型的genericFactory和Func<object>类型的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 }); } }
/// <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); }
/// <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); }
/// <summary>Specify the reuse type and the scope name.</summary> public ReuseAttribute(ReuseType reuseType, params object[] scopeNames) { ReuseType = reuseType; ScopeNames = scopeNames; }
/// <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); }
/// <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; }
/// <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); }
/// <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); }
/// <summary> /// Initialize<br/> /// 初始化<br/> /// </summary> /// <param name="reuseType">Reuse type</param> public ReuseAttribute(ReuseType reuseType) { ReuseType = reuseType; }
/// <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)); } }