private void InitializeRootRegistry() { Register = AddOrReplace; // Create Registry and set Factory strategy _metadata = new Registry <Type, int[]>(); _registry = new Registry <NamedType, IPolicySet>(new DefaultPolicies(OptimizingFactory)); // Register Container as IUnityContainer & IUnityContainerAsync var container = new ExplicitRegistration(typeof(UnityContainer), _containerManager) { BuildChain = new[] { new LifetimeStrategy() } }; // Built-In Features _registry.Set(typeof(IUnityContainer), null, container); _registry.Set(typeof(IUnityContainerAsync), null, container); // Func<> Factory var funcBuiltInFctory = new ImplicitRegistration(); funcBuiltInFctory.Set(typeof(LifetimeManager), new PerResolveLifetimeManager()); funcBuiltInFctory.Set(typeof(ResolveDelegateFactory), FuncResolver.Factory); _registry.Set(typeof(Func <>), funcBuiltInFctory); // Lazy<> _registry.Set(typeof(Lazy <>), new ImplicitRegistration(typeof(ResolveDelegateFactory), LazyResolver.Factory)); // Enumerable _registry.Set(typeof(IEnumerable <>), new ImplicitRegistration(typeof(ResolveDelegateFactory), EnumerableResolver.Factory)); }
/// <inheritdoc /> IUnityContainer IUnityContainerAsync.RegisterFactory(IEnumerable <Type> interfaces, string name, Func <IUnityContainer, Type, string, object> factory, IFactoryLifetimeManager lifetimeManager) { // Validate input // TODO: Move to diagnostic if (null == interfaces) { throw new ArgumentNullException(nameof(interfaces)); } if (null == factory) { throw new ArgumentNullException(nameof(factory)); } if (null == lifetimeManager) { lifetimeManager = TransientLifetimeManager.Instance; } if (((LifetimeManager)lifetimeManager).InUse) { throw new InvalidOperationException(LifetimeManagerInUse); } // Create registration and add to appropriate storage var container = lifetimeManager is SingletonLifetimeManager ? _root : this; // TODO: InjectionFactory #pragma warning disable CS0618 var injectionFactory = new InjectionFactory(factory); #pragma warning restore CS0618 var injectionMembers = new InjectionMember[] { injectionFactory }; var registration = new ExplicitRegistration(_validators, (LifetimeManager)lifetimeManager, injectionMembers); // Add Injection Members //injectionFactory.AddPolicies<BuilderContext, ContainerRegistration>( // type, type, name, ref registration); // Register interfaces var replaced = container.AddOrReplaceRegistrations(interfaces, name, registration) .ToArray(); // Release replaced registrations if (0 != replaced.Length) { Task.Factory.StartNew(() => { foreach (ImplicitRegistration previous in replaced) { if (0 == previous.Release() && previous.LifetimeManager is IDisposable disposable) { // Dispose replaced lifetime manager container.LifetimeContainer.Remove(disposable); disposable.Dispose(); } } }); } return(this); }
public PipelineBuilder(ExplicitRegistration registration, UnityContainer container, IEnumerable <Pipeline> pipelines) { Type = registration.Type ?? typeof(object); Registration = registration; ContainerContext = container.Context; Seed = null; _enumerator = pipelines.GetEnumerator(); }
/// <inheritdoc /> IUnityContainer IUnityContainerAsync.RegisterInstance(IEnumerable <Type> interfaces, string name, object instance, IInstanceLifetimeManager lifetimeManager) { // Validate input // TODO: Move to diagnostic if (null == interfaces && null == instance) { throw new ArgumentNullException(nameof(interfaces)); } // Validate lifetime manager if (null == lifetimeManager) { lifetimeManager = new ContainerControlledLifetimeManager(); } if (((LifetimeManager)lifetimeManager).InUse) { throw new InvalidOperationException(LifetimeManagerInUse); } ((LifetimeManager)lifetimeManager).SetValue(instance, LifetimeContainer); // Create registration and add to appropriate storage var mappedToType = instance?.GetType(); var container = lifetimeManager is SingletonLifetimeManager ? _root : this; var registration = new ExplicitRegistration(mappedToType, (LifetimeManager)lifetimeManager); // If Disposable add to container's lifetime if (lifetimeManager is IDisposable manager) { container.LifetimeContainer.Add(manager); } // Register interfaces var replaced = container.AddOrReplaceRegistrations(interfaces, name, registration) .ToArray(); // Release replaced registrations if (0 != replaced.Length) { Task.Factory.StartNew(() => { foreach (ImplicitRegistration previous in replaced) { if (0 == previous.Release() && previous.LifetimeManager is IDisposable disposable) { // Dispose replaced lifetime manager container.LifetimeContainer.Remove(disposable); disposable.Dispose(); } } }); } return(this); }
private ExplicitRegistration?AddOrReplace(Type type, string?name, ExplicitRegistration registration) { var collisions = 0; var key = new HashKey(type, name); var metaKey = new HashKey(type); Debug.Assert(null != _registry); Debug.Assert(null != _metadata); registration.AddRef(); // Registry lock (_syncRegistry) { var targetBucket = key.HashCode % _registry.Buckets.Length; for (var i = _registry.Buckets[targetBucket]; i >= 0; i = _registry.Entries[i].Next) { ref var candidate = ref _registry.Entries[i]; if (candidate.Key != key) { collisions++; continue; } // Swap the registration var existing = candidate.Policies as ExplicitRegistration; if (null == existing) { candidate.IsExplicit = true; registration.Add(candidate.Policies); } candidate.Policies = registration; candidate.Pipeline = registration.Pipeline; candidate.Registration = registration; // Replaced registration return(existing); } // Expand if required if (_registry.RequireToGrow || CollisionsCutPoint < collisions) { _registry = new Registry(_registry); targetBucket = key.HashCode % _registry.Buckets.Length; } // Create new entry ref var entry = ref _registry.Entries[_registry.Count];
public void Add(Type type, ExplicitRegistration registration) { var key = new HashKey(type, registration.Name); var bucket = key.HashCode % _buckets.Length; var collisionCount = 0; for (int i = _buckets[bucket]; --i >= 0; i = _entries[i].Next) { ref var entry = ref _entries[i]; if (entry.Key == key) { entry.Registration = registration; return; } collisionCount++; }
private ExplicitRegistration?InitAndAdd(Type type, string?name, ExplicitRegistration registration) { lock (_syncRegistry) { if (null == _registry) { _registry = new Registry(); } if (null == _metadata) { _metadata = new Metadata(); Register = AddOrReplace; } } return(Register(type, name, registration)); }
// Pipeline from factory public PipelineBuilder(Type type, ExplicitRegistration factory, LifetimeManager manager, UnityContainer owner) { Type = type; Seed = factory.Pipeline; TypeConverter = factory.BuildType; LifetimeManager = manager; InjectionMembers = factory.InjectionMembers; Factory = factory; Policies = factory; Registration = null; IsMapping = null != factory.BuildType; // TODO: Move to registration BuildRequired = null != factory.InjectionMembers && factory.InjectionMembers.Any(m => m.BuildRequired); ContainerContext = owner.Context; Debug.Assert(null != factory.Processors); _enumerator = factory.Processors.GetEnumerator(); }
// Pipeline From Registration public PipelineBuilder(Type type, ExplicitRegistration registration) { Debug.Assert(null != registration.Type); Type = type; TypeConverter = null; LifetimeManager = registration.LifetimeManager; InjectionMembers = registration.InjectionMembers; Factory = null; Policies = registration; Registration = registration; IsMapping = null != registration.Type && type != registration.Type; BuildRequired = registration.BuildRequired; Seed = registration.Pipeline; ContainerContext = registration.Owner.Context; Debug.Assert(null != registration?.Processors); _enumerator = registration.Processors.GetEnumerator(); }
/// <inheritdoc /> IUnityContainer IUnityContainer.RegisterInstance(Type type, string name, object instance, IInstanceLifetimeManager lifetimeManager) { var mappedToType = instance?.GetType(); var registeredType = type ?? mappedToType; try { // Validate input if (null == registeredType) { throw new InvalidOperationException($"At least one of Type arguments '{nameof(type)}' or '{nameof(instance)}' must be not 'null'"); } if (null == lifetimeManager) { lifetimeManager = new ContainerControlledLifetimeManager(); } if (((LifetimeManager)lifetimeManager).InUse) { throw new InvalidOperationException(LifetimeManagerInUse); } ((LifetimeManager)lifetimeManager).SetValue(instance, LifetimeContainer); // Create registration and add to appropriate storage var container = lifetimeManager is SingletonLifetimeManager ? _root : this; var registration = new ExplicitRegistration(null, mappedToType, ((LifetimeManager)lifetimeManager)); // If Disposable add to container's lifetime if (lifetimeManager is IDisposable manager) { container.LifetimeContainer.Add(manager); } // Register type var previous = container.Register(registeredType, name, registration); // Allow reference adjustment and disposal if (null != previous && 0 == previous.Release() && previous.LifetimeManager is IDisposable disposable) { // Dispose replaced lifetime manager container.LifetimeContainer.Remove(disposable); disposable.Dispose(); } // Check what strategies to run registration.BuildChain = _strategiesChain.ToArray() .Where(strategy => strategy.RequiredToResolveInstance(this, registration)) .ToArray(); // Raise event container.RegisteringInstance?.Invoke(this, new RegisterInstanceEventArgs(registeredType, instance, name, ((LifetimeManager)lifetimeManager))); } catch (Exception ex) { var parts = new List <string>(); if (null != name) { parts.Add($" '{name}'"); } if (null != lifetimeManager && !(lifetimeManager is TransientLifetimeManager)) { parts.Add(lifetimeManager.ToString()); } var message = $"Error in RegisterInstance<{registeredType?.Name}>({string.Join(", ", parts)})"; throw new InvalidOperationException(message, ex); } return(this); }
/// <summary> /// Create a default <see cref="UnityContainer"/>. /// </summary> public UnityContainer(ModeFlags mode = ModeFlags.Optimized) { if (!mode.IsValid()) { throw new ArgumentException("'Activated' and 'Diagnostic' flags are mutually exclusive."); } ///////////////////////////////////////////////////////////// // Initialize Root _root = this; ExecutionMode = mode; LifetimeContainer = new LifetimeContainer(this); Register = AddOrReplace; //Built-In Registrations // Defaults Defaults = new DefaultPolicies(this); // IUnityContainer, IUnityContainerAsync var container = new ExplicitRegistration(this, null, typeof(UnityContainer), new ContainerLifetimeManager()) { Pipeline = (ref PipelineContext c) => c.Container }; Debug.Assert(null != container.LifetimeManager); // Create Registries _metadata = new Metadata(); _registry = new Registry(Defaults); _registry.Set(typeof(IUnityContainer), null, container); // TODO: Remove redundancy _registry.Set(typeof(IUnityContainerAsync), null, container); _registry.Set(typeof(IUnityContainer), null, container.LifetimeManager.Pipeline); _registry.Set(typeof(IUnityContainerAsync), null, container.LifetimeManager.Pipeline); ///////////////////////////////////////////////////////////// // Built-In Features var func = new PolicySet(this); _registry.Set(typeof(Func <>), func); func.Set(typeof(LifetimeManager), new PerResolveLifetimeManager()); func.Set(typeof(TypeFactoryDelegate), FuncResolver.Factory); // Func<> Factory _registry.Set(typeof(Lazy <>), new PolicySet(this, typeof(TypeFactoryDelegate), LazyResolver.Factory)); // Lazy<> _registry.Set(typeof(IEnumerable <>), new PolicySet(this, typeof(TypeFactoryDelegate), EnumerableResolver.Factory)); // Enumerable _registry.Set(typeof(IRegex <>), new PolicySet(this, typeof(TypeFactoryDelegate), RegExResolver.Factory)); // Regular Expression Enumerable ///////////////////////////////////////////////////////////// // Pipelines var typeFactory = new TypeFactoryPipeline(); var lifetime = new LifetimePipeline(); // Mode of operation if (ExecutionMode.IsDiagnostic()) { ///////////////////////////////////////////////////////////// // Setup Diagnostic mode var diagnostic = new DiagnosticPipeline(); // Create Context Context = new ContainerContext(this, new StagedStrategyChain <Pipeline, Stage> // Type Build Pipeline { { diagnostic, Stage.Diagnostic }, { typeFactory, Stage.Factory }, { new MappingDiagnostic(), Stage.TypeMapping }, { new ConstructorDiagnostic(this), Stage.Creation }, { new FieldDiagnostic(this), Stage.Fields }, { new PropertyDiagnostic(this), Stage.Properties }, { new MethodDiagnostic(this), Stage.Methods } }, new StagedStrategyChain <Pipeline, Stage> // Factory Resolve Pipeline { { diagnostic, Stage.Diagnostic }, { new FactoryPipeline(), Stage.Factory } }, new StagedStrategyChain <Pipeline, Stage> // Instance Resolve Pipeline { { diagnostic, Stage.Diagnostic }, { typeFactory, Stage.Factory } }); // Build process DependencyResolvePipeline = ValidatingDependencyResolvePipeline; // Validators ValidateType = DiagnosticValidateType; ValidateTypes = DiagnosticValidateTypes; CreateErrorMessage = CreateDiagnosticMessage; } else { // Create Context Context = new ContainerContext(this, new StagedStrategyChain <Pipeline, Stage> // Type Build Pipeline { { lifetime, Stage.Lifetime }, { typeFactory, Stage.Factory }, { new MappingPipeline(), Stage.TypeMapping }, { new ConstructorPipeline(this), Stage.Creation }, { new FieldPipeline(this), Stage.Fields }, { new PropertyPipeline(this), Stage.Properties }, { new MethodPipeline(this), Stage.Methods } }, new StagedStrategyChain <Pipeline, Stage> // Factory Resolve Pipeline { { lifetime, Stage.Lifetime }, { new FactoryPipeline(), Stage.Factory } }, new StagedStrategyChain <Pipeline, Stage> // Instance Resolve Pipeline { { typeFactory, Stage.Factory } }); } ///////////////////////////////////////////////////////////// // Build Mode var build = _root.ExecutionMode.BuildMode(); PipelineFromRegistration = build switch { ModeFlags.Activated => PipelineFromRegistrationActivated, ModeFlags.Compiled => PipelineFromRegistrationCompiled, _ => (FromRegistration)PipelineFromRegistrationOptimized }; PipelineFromUnregisteredType = build switch { ModeFlags.Activated => PipelineFromUnregisteredTypeActivated, ModeFlags.Compiled => PipelineFromUnregisteredTypeCompiled, _ => (FromUnregistered)PipelineFromUnregisteredTypeOptimized }; PipelineFromOpenGeneric = build switch { ModeFlags.Activated => PipelineFromOpenGenericActivated, ModeFlags.Compiled => PipelineFromOpenGenericCompiled, _ => (FromOpenGeneric)PipelineFromOpenGenericOptimized }; }
/// <inheritdoc /> public IUnityContainer RegisterFactory(Type type, string?name, Func <IUnityContainer, Type, string?, object?> factory, IFactoryLifetimeManager?lifetimeManager) { // Validate input if (null == type) { throw new ArgumentNullException(nameof(type)); } if (null == factory) { throw new ArgumentNullException(nameof(factory)); } // Lifetime Manager var manager = lifetimeManager as LifetimeManager ?? Context.FactoryLifetimeManager.CreateLifetimePolicy(); if (manager.InUse) { throw new InvalidOperationException(LifetimeManagerInUse); } manager.InUse = true; // Target Container var container = manager is SingletonLifetimeManager ? _root : this; Debug.Assert(null != container); // If Disposable add to container's lifetime if (manager is IDisposable managerDisposable) { container.LifetimeContainer.Add(managerDisposable); } // Create registration var registration = new ExplicitRegistration(container, name, type, manager); // Factory resolver var resolver = lifetimeManager is PerResolveLifetimeManager ? (ResolveDelegate <BuilderContext>)((ref BuilderContext c) => { c.Existing = factory(c.Container, c.Type, c.Name); c.Set(typeof(LifetimeManager), new InternalPerResolveLifetimeManager(c.Existing)); return(c.Existing); }) : ((ref BuilderContext c) => factory(c.Container, c.Type, c.Name)); registration.Set(typeof(ResolveDelegate <BuilderContext>), resolver); // Register var previous = container.Register(type, name, registration); // Allow reference adjustment and disposal if (null != previous && 0 == previous.Release() && previous.LifetimeManager is IDisposable disposable) { // Dispose replaced lifetime manager container.LifetimeContainer.Remove(disposable); disposable.Dispose(); } // Check what strategies to run registration.Processors = Context.FactoryPipelineCache; // Raise event container.Registering?.Invoke(this, new RegisterEventArgs(type, type, name, manager)); // Return Container return(this); }
/// <inheritdoc /> IUnityContainer IUnityContainer.RegisterType(Type typeFrom, Type typeTo, string name, ITypeLifetimeManager lifetimeManager, InjectionMember[] injectionMembers) { try { var mappedToType = typeTo; var registeredType = typeFrom ?? typeTo; // Validate input if (null == typeTo) { throw new ArgumentNullException(nameof(typeTo)); } if (null == lifetimeManager) { lifetimeManager = TransientLifetimeManager.Instance; } if (((LifetimeManager)lifetimeManager).InUse) { throw new InvalidOperationException(LifetimeManagerInUse); } // Validate if they are assignable TypeValidator?.Invoke(typeFrom, typeTo); // Create registration and add to appropriate storage var container = lifetimeManager is SingletonLifetimeManager ? _root : this; var registration = new ExplicitRegistration(_validators, typeTo, (LifetimeManager)lifetimeManager, injectionMembers); // If Disposable add to container's lifetime if (lifetimeManager is IDisposable disposableManager) { container.LifetimeContainer.Add(disposableManager); } // Add or replace existing var previous = container.Register(registeredType, name, registration); // Allow reference adjustment and disposal if (null != previous && 0 == previous.Release() && previous.LifetimeManager is IDisposable disposable) { // Dispose replaced lifetime manager container.LifetimeContainer.Remove(disposable); disposable.Dispose(); } // Add Injection Members if (null != injectionMembers && injectionMembers.Length > 0) { foreach (var member in injectionMembers) { member.AddPolicies <BuilderContext, ExplicitRegistration>( registeredType, mappedToType, name, ref registration); } } // Check what strategies to run registration.BuildChain = _strategiesChain.ToArray() .Where(strategy => strategy.RequiredToBuildType(this, registeredType, registration, injectionMembers)) .ToArray(); // Raise event container.Registering?.Invoke(this, new RegisterEventArgs(registeredType, mappedToType, name, ((LifetimeManager)lifetimeManager))); } catch (Exception ex) { var builder = new StringBuilder(); builder.AppendLine(ex.Message); builder.AppendLine(); var parts = new List <string>(); var generics = null == typeFrom ? typeTo?.Name : $"{typeFrom?.Name},{typeTo?.Name}"; if (null != name) { parts.Add($" '{name}'"); } if (null != lifetimeManager && !(lifetimeManager is TransientLifetimeManager)) { parts.Add(lifetimeManager.ToString()); } if (null != injectionMembers && 0 != injectionMembers.Length) { parts.Add(string.Join(" ,", injectionMembers.Select(m => m.ToString()))); } builder.AppendLine($" Error in: RegisterType<{generics}>({string.Join(", ", parts)})"); throw new InvalidOperationException(builder.ToString(), ex); } return(this); }
/// <inheritdoc /> public IUnityContainer RegisterFactory(Type type, string name, Func <IUnityContainer, Type, string, object> factory, IFactoryLifetimeManager lifetimeManager) { // Validate input if (null == type) { throw new ArgumentNullException(nameof(type)); } if (null == factory) { throw new ArgumentNullException(nameof(factory)); } if (null == lifetimeManager) { lifetimeManager = TransientLifetimeManager.Instance; } if (((LifetimeManager)lifetimeManager).InUse) { throw new InvalidOperationException(LifetimeManagerInUse); } // Create registration and add to appropriate storage var container = lifetimeManager is SingletonLifetimeManager ? _root : this; #pragma warning disable CS0618 // TODO: InjectionFactory var injectionFactory = new InjectionFactory(factory); #pragma warning restore CS0618 var injectionMembers = new InjectionMember[] { injectionFactory }; var registration = new ExplicitRegistration(_validators, type, ((LifetimeManager)lifetimeManager), injectionMembers); // Add or replace existing var previous = container.Register(type, name, registration); // Allow reference adjustment and disposal if (null != previous && 0 == previous.Release() && previous.LifetimeManager is IDisposable disposable) { // Dispose replaced lifetime manager container.LifetimeContainer.Remove(disposable); disposable.Dispose(); } // If Disposable add to container's lifetime if (lifetimeManager is IDisposable manager) { container.LifetimeContainer.Add(manager); } // Add Injection Members injectionFactory.AddPolicies <BuilderContext, ExplicitRegistration>( type, type, name, ref registration); // Check what strategies to run registration.BuildChain = _strategiesChain.ToArray() .Where(strategy => strategy.RequiredToBuildType(this, type, registration, injectionMembers)) .ToArray(); // Raise event container.Registering?.Invoke(this, new RegisterEventArgs(type, type, name, ((LifetimeManager)lifetimeManager))); return(this); }
/// <inheritdoc /> IUnityContainer IUnityContainer.RegisterType(Type typeFrom, Type typeTo, string name, ITypeLifetimeManager lifetimeManager, InjectionMember[] injectionMembers) { // Validate input var registeredType = ValidateType(typeFrom, typeTo); try { // Lifetime Manager var manager = lifetimeManager as LifetimeManager ?? Context.TypeLifetimeManager.CreateLifetimePolicy(); if (manager.InUse) { throw new InvalidOperationException(LifetimeManagerInUse); } manager.InUse = true; // Create registration and add to appropriate storage var container = manager is SingletonLifetimeManager ? _root : this; Debug.Assert(null != container); // If Disposable add to container's lifetime if (manager is IDisposable disposableManager) { container.LifetimeContainer.Add(disposableManager); } // Add or replace existing var registration = new ExplicitRegistration(container, name, typeTo, manager, injectionMembers); var previous = container.Register(registeredType, name, registration); // Allow reference adjustment and disposal if (null != previous && 0 == previous.Release() && previous.LifetimeManager is IDisposable disposable) { // Dispose replaced lifetime manager container.LifetimeContainer.Remove(disposable); disposable.Dispose(); } // Add Injection Members if (null != injectionMembers && injectionMembers.Length > 0) { foreach (var member in injectionMembers) { member.AddPolicies <PipelineContext, ExplicitRegistration>( registeredType, typeTo, name, ref registration); } } // Check what strategies to run registration.Processors = Context.TypePipelineCache; // Raise event container.Registering?.Invoke(this, new RegisterEventArgs(registeredType, typeTo, name, manager)); } catch (Exception ex) { var builder = new StringBuilder(); builder.AppendLine(ex.Message); builder.AppendLine(); var parts = new List <string>(); var generics = null == typeFrom ? typeTo?.Name : $"{typeFrom?.Name},{typeTo?.Name}"; if (null != name) { parts.Add($" '{name}'"); } if (null != lifetimeManager && !(lifetimeManager is TransientLifetimeManager)) { parts.Add(lifetimeManager.ToString()); } if (null != injectionMembers && 0 != injectionMembers.Length) { parts.Add(string.Join(" ,", injectionMembers.Select(m => m.ToString()))); } builder.AppendLine($" Error in: RegisterType<{generics}>({string.Join(", ", parts)})"); throw new InvalidOperationException(builder.ToString(), ex); } return(this); }
/// <inheritdoc /> IUnityContainer IUnityContainer.RegisterInstance(Type?type, string?name, object?instance, IInstanceLifetimeManager?lifetimeManager) { var mappedToType = instance?.GetType(); var registeredType = type ?? mappedToType; // Validate input if (null == registeredType) { throw new InvalidOperationException($"At least one of Type arguments '{nameof(type)}' or '{nameof(instance)}' must be not 'null'"); } try { // Lifetime Manager var manager = lifetimeManager as LifetimeManager ?? Context.InstanceLifetimeManager.CreateLifetimePolicy(); if (manager.InUse) { throw new InvalidOperationException(LifetimeManagerInUse); } manager.InUse = true; if (manager is ILifetimeManagerAsync managerAsync) { managerAsync.SetResult(instance, LifetimeContainer); } else { manager.SetValue(instance, LifetimeContainer); } // Create registration and add to appropriate storage var container = manager is SingletonLifetimeManager ? _root : this; Debug.Assert(null != container); // If Disposable add to container's lifetime if (manager is IDisposable disposableManager) { container.LifetimeContainer.Add(disposableManager); } // Register type var registration = new ExplicitRegistration(container, name, mappedToType ?? registeredType, manager); var previous = container.Register(registeredType, name, registration); // Allow reference adjustment and disposal if (null != previous && 0 == previous.Release() && previous.LifetimeManager is IDisposable disposable) { // Dispose replaced lifetime manager container.LifetimeContainer.Remove(disposable); disposable.Dispose(); } // Check what strategies to run registration.Processors = Context.InstancePipelineCache; // Raise event container.RegisteringInstance?.Invoke(this, new RegisterInstanceEventArgs(registeredType, instance, name, manager)); } catch (Exception ex) { var parts = new List <string>(); if (null != name) { parts.Add($" '{name}'"); } var message = $"Error in RegisterInstance<{registeredType?.Name}>({string.Join(", ", parts)})"; throw new InvalidOperationException(message, ex); } return(this); }
/// <inheritdoc /> Task IUnityContainerAsync.RegisterFactory(IEnumerable <Type>?interfaces, string?name, Func <IUnityContainer, Type, string?, object?> factory, IFactoryLifetimeManager?lifetimeManager) { // Validate input if (null == interfaces) { throw new ArgumentNullException(nameof(interfaces)); } if (null == factory) { throw new ArgumentNullException(nameof(factory)); } return(Task.Factory.StartNew(() => { // TODO: implementation required var type = interfaces.First(); // Lifetime Manager var manager = lifetimeManager as LifetimeManager ?? Context.FactoryLifetimeManager.CreateLifetimePolicy(); if (manager.InUse) { throw new InvalidOperationException(LifetimeManagerInUse); } manager.InUse = true; // Target Container var container = manager is SingletonLifetimeManager ? _root : this; Debug.Assert(null != container); // If Disposable add to container's lifetime if (manager is IDisposable managerDisposable) { container.LifetimeContainer.Add(managerDisposable); } // Create registration var registration = new ExplicitRegistration(container, name, type, manager); // Factory resolver var resolver = lifetimeManager is PerResolveLifetimeManager ? (ResolveDelegate <BuilderContext>)((ref BuilderContext c) => { c.Existing = factory(c.Container, c.Type, c.Name); c.Set(typeof(LifetimeManager), new InternalPerResolveLifetimeManager(c.Existing)); return c.Existing; }) : ((ref BuilderContext c) => factory(c.Container, c.Type, c.Name)); registration.Set(typeof(ResolveDelegate <BuilderContext>), resolver); // Build Pipeline PipelineBuilder builder = new PipelineBuilder(registration, container, Context.FactoryPipelineCache); registration.Pipeline = builder.Pipeline(); // Register var previous = container.Register(type, name, registration); // Allow reference adjustment and disposal if (null != previous && 0 == previous.Release() && previous.LifetimeManager is IDisposable disposable) { // Dispose replaced lifetime manager container.LifetimeContainer.Remove(disposable); disposable.Dispose(); } // TODO: Raise event // container.Registering?.Invoke(this, new RegisterEventArgs(type, type, name, manager)); })); }
/// <inheritdoc /> Task IUnityContainerAsync.RegisterType(IEnumerable <Type>?interfaces, Type type, string?name, ITypeLifetimeManager?lifetimeManager, params InjectionMember[] injectionMembers) { return(Task.Factory.StartNew((object status) => { var types = status as Type[]; Type?typeFrom = null; var registeredType = typeFrom ?? type; // Validate input //if (null == registeredType) throw new InvalidOperationException($"At least one of Type arguments '{nameof(typeFrom)}' or '{nameof(typeTo)}' must be not 'null'"); try { // Lifetime Manager var manager = lifetimeManager as LifetimeManager ?? Context.TypeLifetimeManager.CreateLifetimePolicy(); if (manager.InUse) { throw new InvalidOperationException(LifetimeManagerInUse); } manager.InUse = true; // Create registration and add to appropriate storage var container = manager is SingletonLifetimeManager ? _root : this; Debug.Assert(null != container); // If Disposable add to container's lifetime if (manager is IDisposable disposableManager) { container.LifetimeContainer.Add(disposableManager); } // Add or replace existing var registration = new ExplicitRegistration(container, name, type, manager, injectionMembers); var previous = container.Register(registeredType, name, registration); // Allow reference adjustment and disposal if (null != previous && 0 == previous.Release() && previous.LifetimeManager is IDisposable disposable) { // Dispose replaced lifetime manager container.LifetimeContainer.Remove(disposable); disposable.Dispose(); } // Add Injection Members if (null != injectionMembers && injectionMembers.Length > 0) { foreach (var member in injectionMembers) { member.AddPolicies <BuilderContext, ExplicitRegistration>( registeredType, type, name, ref registration); } } // Check what strategies to run registration.Processors = Context.TypePipelineCache; // Raise event //container.Registering?.Invoke(this, new RegisterEventArgs(registeredType, // typeTo, // name, // manager)); } catch (Exception ex) { var builder = new StringBuilder(); builder.AppendLine(ex.Message); builder.AppendLine(); var parts = new List <string>(); var generics = null == typeFrom ? type?.Name : $"{typeFrom?.Name},{type?.Name}"; if (null != name) { parts.Add($" '{name}'"); } if (null != lifetimeManager && !(lifetimeManager is TransientLifetimeManager)) { parts.Add(lifetimeManager.ToString()); } if (null != injectionMembers && 0 != injectionMembers.Length) { parts.Add(string.Join(" ,", injectionMembers.Select(m => m.ToString()))); } builder.AppendLine($" Error in: RegisterType<{generics}>({string.Join(", ", parts)})"); throw new InvalidOperationException(builder.ToString(), ex); } }, ValidateTypes(interfaces, type))); }
private ResolveDelegate <PipelineContext> PipelineFromOpenGenericOptimized(ref HashKey key, ExplicitRegistration factory) { Debug.Assert(null != _registry); Debug.Assert(null != key.Type); LifetimeManager?manager = null; ResolveDelegate <PipelineContext>?pipeline = null; // Add Pipeline to the Registry lock (_syncRegistry) { bool adding = true; var collisions = 0; var targetBucket = key.HashCode % _registry.Buckets.Length; for (var i = _registry.Buckets[targetBucket]; i >= 0; i = _registry.Entries[i].Next) { ref var candidate = ref _registry.Entries[i]; if (candidate.Key != key) { collisions++; continue; } // Pipeline already been created if (null != candidate.Pipeline) { return(candidate.Pipeline); } // Lifetime Manager manager = Context.TypeLifetimeManager.CreateLifetimePolicy(); manager.PipelineDelegate = (ResolveDelegate <PipelineContext>)SpinWait; // Type has not been registered if (null == candidate.Registration) { candidate.Pipeline = manager.Pipeline; } adding = false; break; } if (adding) { // Expand if required if (_registry.RequireToGrow || CollisionsCutPoint < collisions) { _registry = new Registry(_registry); targetBucket = key.HashCode % _registry.Buckets.Length; } // Lifetime Manager manager = factory.LifetimeManager.CreateLifetimePolicy(); manager.PipelineDelegate = (ResolveDelegate <PipelineContext>)SpinWait; // Create new entry ref var entry = ref _registry.Entries[_registry.Count]; entry.Key = key; entry.Pipeline = manager.Pipeline; entry.Next = _registry.Buckets[targetBucket]; _registry.Buckets[targetBucket] = _registry.Count++; }
private ResolveDelegate <PipelineContext> PipelineFromRegistrationOptimized(Type?type, ExplicitRegistration registration, int position) { Debug.Assert(null != _registry); Debug.Assert(null != type); var manager = registration.LifetimeManager; ResolveDelegate <PipelineContext>?pipeline = null; lock (_syncRegistry) { ref var entry = ref _registry.Entries[position]; if (ReferenceEquals(entry.Registration, registration) && null == entry.Pipeline) { entry.Pipeline = manager.Pipeline; manager.PipelineDelegate = (ResolveDelegate <PipelineContext>)SpinWait; } }
public RegistrationWrapper(Type type, IPolicySet registration) { RegisteredType = type; _registration = (ExplicitRegistration)registration; }