public override IEnumerable <ExportDescriptorPromise> GetExportDescriptors( CompositionContract contract, DependencyAccessor descriptorAccessor) { if (_logger.IsEnabled(LogLevel.Debug)) { _logger.LogDebug($"Getting Export Descriptors:" + $" contractName=[{contract.ContractName}]" + $" contractType=[{contract.ContractType.FullName}]"); } var svc = _serviceProvider.GetService(contract.ContractType); if (svc == null) { if (_logger.IsEnabled(LogLevel.Debug)) { _logger.LogDebug($"No DI service found for" + $" contractType=[{contract.ContractType.FullName}]"); } yield break; } if (_logger.IsEnabled(LogLevel.Debug)) { _logger.LogDebug($"Resolved DI service for" + $" contractType=[{contract.ContractType.FullName}]" + $" service=[{svc}]"); } CompositeActivator ca = (ctx, op) => svc; yield return(new ExportDescriptorPromise(contract, ORIGIN_NAME, true, NoDependencies, deps => ExportDescriptor.Create(ca, NoMetadata))); }
public override CompositeActivator RewriteActivator( TypeInfo partType, CompositeActivator activatorBody, IDictionary<string, object> partMetadata, IEnumerable<CompositionDependency> dependencies) { if (!ContractHelpers.IsShared(partMetadata)) return activatorBody; object sharingBoundaryMetadata; if (!partMetadata.TryGetValue(SharingBoundaryPartMetadataName, out sharingBoundaryMetadata)) sharingBoundaryMetadata = null; var sharingBoundary = (string)sharingBoundaryMetadata; var sharingKey = LifetimeContext.AllocateSharingId(); return (c, o) => { var scope = c.FindContextWithin(sharingBoundary); if (object.ReferenceEquals(scope, c)) return scope.GetOrCreate(sharingKey, o, activatorBody); else return CompositionOperation.Run(scope, (c1, o1) => c1.GetOrCreate(sharingKey, o1, activatorBody)); }; }
public override CompositeActivator RewriteActivator( TypeInfo partType, CompositeActivator activatorBody, IDictionary <string, object> partMetadata, IEnumerable <CompositionDependency> dependencies) { if (!ContractHelpers.IsShared(partMetadata)) { return(activatorBody); } object sharingBoundaryMetadata; if (!partMetadata.TryGetValue(SharingBoundaryPartMetadataName, out sharingBoundaryMetadata)) { sharingBoundaryMetadata = null; } var sharingBoundary = (string)sharingBoundaryMetadata; var sharingKey = LifetimeContext.AllocateSharingId(); return((c, o) => { var scope = c.FindContextWithin(sharingBoundary); if (object.ReferenceEquals(scope, c)) { return scope.GetOrCreate(sharingKey, o, activatorBody); } else { return CompositionOperation.Run(scope, (c1, o1) => c1.GetOrCreate(sharingKey, o1, activatorBody)); } }); }
public void Create_Valid_ReturnsExpected(CompositeActivator activator, Dictionary <string, object> metadata) { ExportDescriptor descriptor = ExportDescriptor.Create(activator, metadata); Assert.Same(activator, descriptor.Activator); Assert.Same(metadata, descriptor.Metadata); }
public DirectExportDescriptor(CompositeActivator activator, IDictionary<string, object> metadata) { Requires.NotNull(activator, "activator"); Requires.NotNull(metadata, "metadata"); _activator = activator; _metadata = metadata; }
public DirectExportDescriptor(CompositeActivator activator, IDictionary <string, object> metadata) { Requires.NotNull(activator, "activator"); Requires.NotNull(metadata, "metadata"); _activator = activator; _metadata = metadata; }
CompositeActivator CreateActivator(IEnumerable <CompositionDependency> dependencies) { var dependenciesByImport = dependencies.GroupBy(d => (ContractBasedImportDefinition)d.Site, d => d.Target.GetDescriptor()); var prereqs = dependenciesByImport.Where(d => d.Key.IsPrerequisite).ToArray(); var nonprereqs = dependenciesByImport.Where(d => !d.Key.IsPrerequisite).ToArray(); var unset = _part.ImportDefinitions.Where(id => !prereqs.Concat(nonprereqs).Any(k => k.Key.Equals((ContractBasedImportDefinition)id))).ToArray(); CompositeActivator construct = (c, o) => { var result = _part.CreatePart(); if (result is IDisposable) { c.AddBoundInstance((IDisposable)result); } foreach (var pre in prereqs) { result.SetImport(pre.Key, DependenciesToExports(c, pre)); } foreach (var un in unset) { result.SetImport(un, Enumerable.Empty <Export>()); } o.AddNonPrerequisiteAction(() => { foreach (var np in nonprereqs) { result.SetImport(np.Key, DependenciesToExports(c, np)); } }); o.AddPostCompositionAction(() => { result.Activate(); }); return(result); }; if (!IsShared) { return(construct); } var sharingId = LifetimeContext.AllocateSharingId(); CompositeActivator constructAndShare = (c, o) => c.GetOrCreate(sharingId, o, construct); return((c, o) => { var scope = c.FindContextWithin(_boundary); return scope.Equals(c) ? constructAndShare(scope, o) : CompositionOperation.Run(scope, constructAndShare); }); }
public CompositeActivator GetActivator(IEnumerable <CompositionDependency> dependencies) { if (_activator == null) { _activator = CreateActivator(dependencies); } return(_activator); }
public override CompositeActivator RewriteActivator( TypeInfo partType, CompositeActivator activator, IDictionary <string, object> partMetadata, IEnumerable <CompositionDependency> dependencies) { var propertyDependencies = dependencies .Where(dep => dep.Site is PropertyImportSite) .ToDictionary(d => ((PropertyImportSite)d.Site).Property); if (propertyDependencies.Count == 0) { return(activator); } var lc = Expression.Parameter(typeof(LifetimeContext)); var op = Expression.Parameter(typeof(CompositionOperation)); var inst = Expression.Parameter(typeof(object)); var typed = Expression.Variable(partType.AsType()); var statements = new List <Expression>(); var assignTyped = Expression.Assign(typed, Expression.Convert(inst, partType.AsType())); statements.Add(assignTyped); foreach (var d in propertyDependencies) { var property = d.Key; var assignment = Expression.Assign( Expression.MakeMemberAccess(typed, property), Expression.Convert( Expression.Call( Expression.Constant(d.Value.Target.GetDescriptor().Activator), ActivatorInvokeMethod, lc, op), property.PropertyType)); statements.Add(assignment); } statements.Add(inst); var setAll = Expression.Block(new[] { typed }, statements); var setAction = Expression.Lambda <Func <object, LifetimeContext, CompositionOperation, object> >( setAll, inst, lc, op).Compile(); return((c, o) => { var i = activator(c, o); o.AddNonPrerequisiteAction(() => setAction(i, c, o)); return i; }); }
/// <summary> /// Execute a new composition operation starting within the specified lifetime /// context, for the specified activator. /// </summary> /// <param name="outermostLifetimeContext">Context in which to begin the operation (the operation can flow /// to the parents of the context if requried).</param> /// <param name="compositionRootActivator">Activator that will drive the operation.</param> /// <returns>The composed object graph.</returns> public static object Run(LifetimeContext outermostLifetimeContext, CompositeActivator compositionRootActivator) { Requires.ArgumentNotNull(outermostLifetimeContext, "outermostLifetimeContext"); Requires.ArgumentNotNull(compositionRootActivator, "compositionRootActivator"); using (var operation = new CompositionOperation()) { var result = compositionRootActivator(outermostLifetimeContext, operation); operation.Complete(); return(result); } }
/// <summary> /// Execute a new composition operation starting within the specified lifetime /// context, for the specified activator. /// </summary> /// <param name="outermostLifetimeContext">Context in which to begin the operation (the operation can flow /// to the parents of the context if requried).</param> /// <param name="compositionRootActivator">Activator that will drive the operation.</param> /// <returns>The composed object graph.</returns> public static object Run(LifetimeContext outermostLifetimeContext, CompositeActivator compositionRootActivator) { Requires.NotNull(outermostLifetimeContext, nameof(outermostLifetimeContext)); Requires.NotNull(compositionRootActivator, nameof(compositionRootActivator)); using (var operation = new CompositionOperation()) { var result = compositionRootActivator(outermostLifetimeContext, operation); operation.Complete(); return result; } }
protected override ExportDescriptor GetExportDescriptor(CompositeActivator partActivator) { var args = new[] { Expression.Parameter(typeof(LifetimeContext)), Expression.Parameter(typeof(CompositionOperation)) }; var activator = Expression.Lambda <CompositeActivator>( Expression.Property( Expression.Convert(Expression.Call(Expression.Constant(partActivator), ActivatorInvoke, args), _property.DeclaringType), _property), args); return(ExportDescriptor.Create(activator.Compile(), Metadata)); }
protected override ExportDescriptor GetExportDescriptor(CompositeActivator partActivator) { var args = new[] { Expression.Parameter(typeof(LifetimeContext)), Expression.Parameter(typeof(CompositionOperation)) }; var activator = Expression.Lambda<CompositeActivator>( Expression.Property( Expression.Convert(Expression.Call(Expression.Constant(partActivator), s_activatorInvoke, args), _property.DeclaringType), _property), args); return ExportDescriptor.Create(activator.Compile(), Metadata); }
public override CompositeActivator RewriteActivator( TypeInfo partType, CompositeActivator activator, IDictionary<string, object> partMetadata, IEnumerable<CompositionDependency> dependencies) { var propertyDependencies = dependencies .Where(dep => dep.Site is PropertyImportSite) .ToDictionary(d => ((PropertyImportSite)d.Site).Property); if (propertyDependencies.Count == 0) return activator; var lc = Expression.Parameter(typeof(LifetimeContext)); var op = Expression.Parameter(typeof(CompositionOperation)); var inst = Expression.Parameter(typeof(object)); var typed = Expression.Variable(partType.AsType()); var statements = new List<Expression>(); var assignTyped = Expression.Assign(typed, Expression.Convert(inst, partType.AsType())); statements.Add(assignTyped); foreach (var d in propertyDependencies) { var property = d.Key; var assignment = Expression.Assign( Expression.MakeMemberAccess(typed, property), Expression.Convert( Expression.Call( Expression.Constant(d.Value.Target.GetDescriptor().Activator), s_activatorInvokeMethod, lc, op), property.PropertyType)); statements.Add(assignment); } statements.Add(inst); var setAll = Expression.Block(new[] { typed }, statements); var setAction = Expression.Lambda<Func<object, LifetimeContext, CompositionOperation, object>>( setAll, inst, lc, op).Compile(); return (c, o) => { var i = activator(c, o); o.AddNonPrerequisiteAction(() => setAction(i, c, o)); return i; }; }
public DirectExportDescriptor(CompositeActivator activator, IDictionary <string, object> metadata) { if (activator == null) { throw new ArgumentNullException(nameof(activator)); } if (metadata == null) { throw new ArgumentNullException(nameof(metadata)); } _activator = activator; _metadata = metadata; }
public DelegateExportDescriptorProvider(Func <object> exportedInstanceFactory, Type contractType, string contractName, IDictionary <string, object> metadata, bool isShared) : base(contractType, contractName, metadata) { if (exportedInstanceFactory == null) { throw new ArgumentNullException("exportedInstanceFactory"); } // Runs the factory method, validates the result and registers it for disposal if necessary. CompositeActivator constructor = (c, o) => { var result = exportedInstanceFactory(); if (result == null) { throw new InvalidOperationException("Delegate factory returned null."); } if (result is IDisposable) { c.AddBoundInstance((IDisposable)result); } return(result); }; if (isShared) { var sharingId = LifetimeContext.AllocateSharingId(); _activator = (c, o) => { // Find the root composition scope. var scope = c.FindContextWithin(null); if (scope == c) { // We're already in the root scope, create the instance return(scope.GetOrCreate(sharingId, o, constructor)); } else { // Composition is moving up the hierarchy of scopes; run // a new operation in the root scope. return(CompositionOperation.Run(scope, (c1, o1) => c1.GetOrCreate(sharingId, o1, constructor))); } }; } else { _activator = constructor; } }
public CompositeActivator GetActivator(DependencyAccessor definitionAccessor, IEnumerable <CompositionDependency> dependencies) { if (_partActivator != null) { return(_partActivator); } var contextParam = Expression.Parameter(typeof(LifetimeContext), "cc"); var operationParm = Expression.Parameter(typeof(CompositionOperation), "op"); var cps = _constructor.GetParameters(); Expression[] paramActivatorCalls = new Expression[cps.Length]; var partActivatorDependencies = dependencies .Where(dep => dep.Site is ParameterImportSite) .ToDictionary(d => ((ParameterImportSite)d.Site).Parameter); for (var i = 0; i < cps.Length; ++i) { var pi = cps[i]; CompositionDependency dep; if (partActivatorDependencies.TryGetValue(pi, out dep)) { var a = dep.Target.GetDescriptor().Activator; paramActivatorCalls[i] = Expression.Convert(Expression.Call(Expression.Constant(a), s_activatorInvoke, contextParam, operationParm), pi.ParameterType); } else { paramActivatorCalls[i] = Expression.Default(pi.ParameterType); } } Expression body = Expression.Convert(Expression.New(_constructor, paramActivatorCalls), typeof(object)); var activator = Expression .Lambda <CompositeActivator>(body, contextParam, operationParm) .Compile(); foreach (var activationFeature in _activationFeatures) { activator = activationFeature.RewriteActivator(_partType, activator, _partMetadata.Value, dependencies); } _partActivator = activator; return(_partActivator); }
public override CompositeActivator RewriteActivator( TypeInfo partType, CompositeActivator activator, IDictionary<string, object> partMetadata, IEnumerable<CompositionDependency> dependencies) { if (!typeof(IDisposable).GetTypeInfo().IsAssignableFrom(partType)) return activator; return (c, o) => { var inst = (IDisposable)activator(c, o); c.AddBoundInstance(inst); return inst; }; }
public ExportDescriptorPromise GetPromise(CompositionContract contract, DependencyAccessor descriptorAccessor) { var origin = _export.ToString(); if (_export is ICompositionElement) { origin = ((ICompositionElement)_export).DisplayName; } return(new ExportDescriptorPromise(contract, origin, _part.IsShared, () => _part.GetDependencies(descriptorAccessor), d => { var partActivator = _part.GetActivator(d); CompositeActivator exportActivator = (c, o) => ((ComposablePart)partActivator(c, o)).GetExportedValue(_export); return ExportDescriptor.Create(exportActivator, _export.Metadata); })); }
public override CompositeActivator RewriteActivator( TypeInfo partType, CompositeActivator activator, IDictionary <string, object> partMetadata, IEnumerable <CompositionDependency> dependencies) { if (!typeof(IDisposable).GetTypeInfo().IsAssignableFrom(partType)) { return(activator); } return((c, o) => { var inst = (IDisposable)activator(c, o); c.AddBoundInstance(inst); return inst; }); }
/// <summary> /// Execute a new composition operation starting within the specified lifetime /// context, for the specified activator. /// </summary> /// <param name="outermostLifetimeContext">Context in which to begin the operation (the operation can flow /// to the parents of the context if required).</param> /// <param name="compositionRootActivator">Activator that will drive the operation.</param> /// <returns>The composed object graph.</returns> public static object Run(LifetimeContext outermostLifetimeContext, CompositeActivator compositionRootActivator) { if (outermostLifetimeContext is null) { throw new ArgumentNullException(nameof(outermostLifetimeContext)); } if (compositionRootActivator is null) { throw new ArgumentNullException(nameof(compositionRootActivator)); } using (var operation = new CompositionOperation()) { var result = compositionRootActivator(outermostLifetimeContext, operation); operation.Complete(); return(result); } }
public void GetDescriptor_CycleActivatorNotCompleted_ThrowsNotImplementedException() { ExportDescriptorPromise promise = null; promise = new ExportDescriptorPromise(new CompositionContract(typeof(int)), "Origin", true, () => Enumerable.Empty <CompositionDependency>(), depdendencies => { ExportDescriptor cycleDescriptor = promise.GetDescriptor(); CompositeActivator activator = cycleDescriptor.Activator; Assert.Throws <NotImplementedException>(() => activator(null, null)); return(ExportDescriptor.Create(Activator, new Dictionary <string, object> { { "key", "value" } })); }); // Invoke the GetDescriptor method to start the test. Assert.NotNull(promise.GetDescriptor()); }
public void GetDescriptor_CycleActivatorNotCompleted_ThrowsInternalErrorException() { ExportDescriptorPromise promise = null; promise = new ExportDescriptorPromise(new CompositionContract(typeof(int)), "Origin", true, () => Enumerable.Empty <CompositionDependency>(), depdendencies => { ExportDescriptor cycleDescriptor = promise.GetDescriptor(); CompositeActivator activator = cycleDescriptor.Activator; Exception ex = Assert.ThrowsAny <Exception>(() => activator(null, null)); Assert.Equal("Microsoft.Internal.Assumes+InternalErrorException", ex.GetType().ToString()); return(ExportDescriptor.Create(Activator, new Dictionary <string, object> { { "key", "value" } })); }); // Invoke the GetDescriptor method to start the test. Assert.NotNull(promise.GetDescriptor()); }
public DelegateExportDescriptorProvider(Func<object> exportedInstanceFactory, Type contractType, string contractName, IDictionary<string, object> metadata, bool isShared) : base (contractType, contractName, metadata) { if (exportedInstanceFactory == null) throw new ArgumentNullException("exportedInstanceFactory"); Contract.EndContractBlock(); // Runs the factory method, validates the result and registers it for disposal if necessary. CompositeActivator constructor = (c, o) => { var result = exportedInstanceFactory(); if (result == null) throw new InvalidOperationException("Delegate factory returned null."); if (result is IDisposable) c.AddBoundInstance((IDisposable)result); return result; }; if (isShared) { var sharingId = LifetimeContext.AllocateSharingId(); _activator = (c, o) => { // Find the root composition scope. var scope = c.FindContextWithin(null); if (scope == c) { // We're already in the root scope, create the instance return scope.GetOrCreate(sharingId, o, constructor); } else { // Composition is moving up the hierarchy of scopes; run // a new operation in the root scope. return CompositionOperation.Run(scope, (c1, o1) => c1.GetOrCreate(sharingId, o1, constructor)); } }; } else { _activator = constructor; } }
public void GetDescriptor_CycleActivatorCompleted_Success() { ExportDescriptorPromise promise = null; CompositeActivator activator = null; promise = new ExportDescriptorPromise(new CompositionContract(typeof(int)), "Origin", true, () => Enumerable.Empty <CompositionDependency>(), depdendencies => { ExportDescriptor cycleDescriptor = promise.GetDescriptor(); activator = cycleDescriptor.Activator; return(ExportDescriptor.Create(Activator, new Dictionary <string, object> { { "key", "value" } })); }); ExportDescriptor descriptor = promise.GetDescriptor(); Assert.Equal("hi", descriptor.Activator(null, null)); Assert.Equal("hi", activator(null, null)); }
/// <summary> /// Either retrieve an existing part instance with the specified sharing id, or /// create and share a new part instance using <paramref name="creator"/> within /// <paramref name="operation"/>. /// </summary> /// <param name="sharingId">Sharing id for the part in question.</param> /// <param name="operation">Operation in which to activate a new part instance if necessary.</param> /// <param name="creator">Activator that can activate a new part instance if necessary.</param> /// <returns>The part instance corresponding to <paramref name="sharingId"/> within this lifetime context.</returns> /// <remarks>This method is lock-free if the part instance already exists. If the part instance must be created, /// a lock will be taken that will serialize other writes via this method (concurrent reads will continue to /// be safe and lock-free). It is important that the composition, and thus lock acquisition, is strictly /// leaf-to-root in the lifetime tree.</remarks> public object GetOrCreate(int sharingId, CompositionOperation operation, CompositeActivator creator) { object result; if (_sharedPartInstances != null && _sharedPartInstances.TryGetValue(sharingId, out result)) { return(result); } // Remains locked for the rest of the operation. operation.EnterSharingLock(_sharingLock); if (_sharedPartInstances == null) { _sharedPartInstances = new SmallSparseInitonlyArray(); _instancesUndergoingInitialization = new SmallSparseInitonlyArray(); } else if (_sharedPartInstances.TryGetValue(sharingId, out result)) { return(result); } // Already being initialized _on the same thread_. if (_instancesUndergoingInitialization.TryGetValue(sharingId, out result)) { return(result); } result = creator(this, operation); _instancesUndergoingInitialization.Add(sharingId, result); operation.AddPostCompositionAction(() => { _sharedPartInstances.Add(sharingId, result); }); return(result); }
public override CompositeActivator RewriteActivator( TypeInfo partType, CompositeActivator activator, IDictionary <string, object> partMetadata, IEnumerable <CompositionDependency> dependencies) { var result = activator; var partTypeAsType = partType.AsType(); var importsSatisfiedMethods = partTypeAsType.GetRuntimeMethods() .Where(mi => _attributeContext.GetDeclaredAttribute <OnImportsSatisfiedAttribute>(mi.DeclaringType, mi) != null); foreach (var m in importsSatisfiedMethods) { if (!(m.IsPublic || m.IsAssembly) | m.IsStatic || m.ReturnType != typeof(void) || m.IsGenericMethodDefinition || m.GetParameters().Length != 0) { var message = string.Format( Properties.Resources.OnImportsSatisfiedFeature_AttributeError, partType, m.Name); throw new CompositionFailedException(message); } var ois = Expression.Parameter(typeof(object), "ois"); var call = Expression.Lambda <Action <object> >( Expression.Call(Expression.Convert(ois, partType.AsType()), m), ois).Compile(); var prev = result; result = (c, o) => { var psn = prev(c, o); o.AddPostCompositionAction(() => call(psn)); return(psn); }; } return(result); }
public override CompositeActivator RewriteActivator( TypeInfo partType, CompositeActivator activator, IDictionary<string, object> partMetadata, IEnumerable<CompositionDependency> dependencies) { var result = activator; var partTypeAsType = partType.AsType(); var importsSatisfiedMethods = partTypeAsType.GetRuntimeMethods() .Where(mi => _attributeContext.GetDeclaredAttribute<OnImportsSatisfiedAttribute>(mi.DeclaringType, mi) != null); foreach (var m in importsSatisfiedMethods) { if (!(m.IsPublic || m.IsAssembly) | m.IsStatic || m.ReturnType != typeof(void) || m.IsGenericMethodDefinition || m.GetParameters().Length != 0) { var message = string.Format( Properties.Resources.OnImportsSatisfiedFeature_AttributeError, partType, m.Name); throw new CompositionFailedException(message); } var ois = Expression.Parameter(typeof(object), "ois"); var call = Expression.Lambda<Action<object>>( Expression.Call(Expression.Convert(ois, partType.AsType()), m), ois).Compile(); var prev = result; result = (c, o) => { var psn = prev(c, o); o.AddPostCompositionAction(() => call(psn)); return psn; }; } return result; }
/// <summary> /// Either retrieve an existing part instance with the specified sharing id, or /// create and share a new part instance using <paramref name="creator"/> within /// <paramref name="operation"/>. /// </summary> /// <param name="sharingId">Sharing id for the part in question.</param> /// <param name="operation">Operation in which to activate a new part instance if necessary.</param> /// <param name="creator">Activator that can activate a new part instance if necessary.</param> /// <returns>The part instance corresponding to <paramref name="sharingId"/> within this lifetime context.</returns> /// <remarks>This method is lock-free if the part instance already exists. If the part instance must be created, /// a lock will be taken that will serialize other writes via this method (concurrent reads will continue to /// be safe and lock-free). It is important that the composition, and thus lock acquisition, is strictly /// leaf-to-root in the lifetime tree.</remarks> public object GetOrCreate(int sharingId, CompositionOperation operation, CompositeActivator creator) { object result; if (_sharedPartInstances != null && _sharedPartInstances.TryGetValue(sharingId, out result)) return result; // Remains locked for the rest of the operation. operation.EnterSharingLock(_sharingLock); if (_sharedPartInstances == null) { _sharedPartInstances = new SmallSparseInitonlyArray(); _instancesUndergoingInitialization = new SmallSparseInitonlyArray(); } else if (_sharedPartInstances.TryGetValue(sharingId, out result)) { return result; } // Already being initialized _on the same thread_. if (_instancesUndergoingInitialization.TryGetValue(sharingId, out result)) return result; result = creator(this, operation); _instancesUndergoingInitialization.Add(sharingId, result); operation.AddPostCompositionAction(() => { _sharedPartInstances.Add(sharingId, result); }); return result; }
public DirectExportDescriptor(CompositeActivator activator !!, IDictionary <string, object> metadata !!)
public object GetOrCreate(int sharingId, CompositionOperation operation, CompositeActivator creator);
public static ExportDescriptor Create(CompositeActivator activator, IDictionary<string, object> metadata);
public static object Run(LifetimeContext outermostLifetimeContext, CompositeActivator compositionRootActivator);
protected abstract ExportDescriptor GetExportDescriptor(CompositeActivator partActivator);
/// <summary> /// Construct an <see cref="ExportDescriptor"/>. /// </summary> /// <param name="activator">The activator used to retrieve instances of the export.</param> /// <param name="metadata">The Export Metadata associated with the export.</param> /// <returns>The export descriptor.</returns> public static ExportDescriptor Create(CompositeActivator activator, IDictionary <string, object> metadata) { return(new DirectExportDescriptor(activator, metadata)); }
protected override ExportDescriptor GetExportDescriptor(CompositeActivator partActivator) { return ExportDescriptor.Create(partActivator, Metadata); }
protected override ExportDescriptor GetExportDescriptor(CompositeActivator partActivator) { return(ExportDescriptor.Create(partActivator, Metadata)); }
/// <summary> /// Construct an <see cref="ExportDescriptor"/>. /// </summary> /// <param name="activator">The activator used to retrieve instances of the export.</param> /// <param name="metadata">The Export Metadata associated with the export.</param> /// <returns>The export descriptor.</returns> public static ExportDescriptor Create(CompositeActivator activator, IDictionary<string, object> metadata) { return new DirectExportDescriptor(activator, metadata); }
/// <summary> /// Participate in the activator creation process. /// </summary> /// <param name="partType">The part type being activated.</param> /// <param name="activator">The activator body so far.</param> /// <param name="partMetadata">Metadata associated with the part being activated.</param> /// <param name="dependencies">Dependencies returned by a previous call to <see cref="GetDependencies"/>.</param> /// <returns>A new activator body, or the one already provided.</returns> public abstract CompositeActivator RewriteActivator( TypeInfo partType, CompositeActivator activator, IDictionary<string, object> partMetadata, IEnumerable<CompositionDependency> dependencies);
public CompositeActivator GetActivator(DependencyAccessor definitionAccessor, IEnumerable<CompositionDependency> dependencies) { if (_partActivator != null) return _partActivator; var contextParam = Expression.Parameter(typeof(LifetimeContext), "cc"); var operationParm = Expression.Parameter(typeof(CompositionOperation), "op"); var cps = _constructor.GetParameters(); Expression[] paramActivatorCalls = new Expression[cps.Length]; var partActivatorDependencies = dependencies .Where(dep => dep.Site is ParameterImportSite) .ToDictionary(d => ((ParameterImportSite)d.Site).Parameter); for (var i = 0; i < cps.Length; ++i) { var pi = cps[i]; CompositionDependency dep; if (partActivatorDependencies.TryGetValue(pi, out dep)) { var a = dep.Target.GetDescriptor().Activator; paramActivatorCalls[i] = Expression.Convert(Expression.Call(Expression.Constant(a), s_activatorInvoke, contextParam, operationParm), pi.ParameterType); } else { paramActivatorCalls[i] = Expression.Default(pi.ParameterType); } } Expression body = Expression.Convert(Expression.New(_constructor, paramActivatorCalls), typeof(object)); var activator = Expression .Lambda<CompositeActivator>(body, contextParam, operationParm) .Compile(); foreach (var activationFeature in _activationFeatures) activator = activationFeature.RewriteActivator(_partType, activator, _partMetadata.Value, dependencies); _partActivator = activator; return _partActivator; }
// The source will only be asked for parts once per exportKey, but it is the // source's responsibility to return the same part multiple times when that part // has more than one export (not shown here.) // public override IEnumerable <ExportDescriptorPromise> GetExportDescriptors(CompositionContract contract, DependencyAccessor definitionAccessor) { if (contract.Equals(new CompositionContract(typeof(RequestListener)))) { return new[] { RequestListenerPart(contract, definitionAccessor) } } ; if (contract.Equals(new CompositionContract(typeof(ConsoleLog)))) { return new[] { ConsoleLogPart(contract, definitionAccessor) } } ; return(NoExportDescriptors); } // Console log is a disposable singleton (no boundaries) // that exports itself under its own concrete type. // ExportDescriptorPromise ConsoleLogPart(CompositionContract contract, DependencyAccessor definitionAccessor) { return(new ExportDescriptorPromise( contract, typeof(ConsoleLog).Name, true, NoDependencies, _ => { var sharingId = LifetimeContext.AllocateSharingId(); return ExportDescriptor.Create((c, o) => { CompositeActivator activatorBody = (sc, so) => { var result = new ConsoleLog(); c.AddBoundInstance(result); return result; }; var scope = c.FindContextWithin(null); if (object.ReferenceEquals(scope, c)) { return scope.GetOrCreate(sharingId, o, activatorBody); } else { return CompositionOperation.Run(scope, (c1, o1) => c1.GetOrCreate(sharingId, o1, activatorBody)); } }, NoMetadata); })); } // Non-shared part that exports itself and has a dependency on ConsoleLog. // ExportDescriptorPromise RequestListenerPart(CompositionContract contract, DependencyAccessor definitionAccessor) { return(new ExportDescriptorPromise( contract, typeof(RequestListener).Name, false, () => new[] { definitionAccessor.ResolveRequiredDependency("log", new CompositionContract(typeof(Lazy <ConsoleLog>)), true) }, dependencies => { var logActivator = dependencies.Single().Target.GetDescriptor().Activator; return ExportDescriptor.Create((c, o) => { var log = (Lazy <ConsoleLog>)logActivator(c, o); return new RequestListener(log); }, NoMetadata); })); } } }
/// <summary> /// Participate in the activator creation process. /// </summary> /// <param name="partType">The part type being activated.</param> /// <param name="activator">The activator body so far.</param> /// <param name="partMetadata">Metadata associated with the part being activated.</param> /// <param name="dependencies">Dependencies returned by a previous call to <see cref="GetDependencies"/>.</param> /// <returns>A new activator body, or the one already provided.</returns> public abstract CompositeActivator RewriteActivator( TypeInfo partType, CompositeActivator activator, IDictionary <string, object> partMetadata, IEnumerable <CompositionDependency> dependencies);