ComponentReference<T>
Reference to component obtained from the container.
using Castle.Core;
using Castle.MicroKernel.Context;
using Castle.MicroKernel.Resolvers;
using System;
using System.Diagnostics;
using System.Linq;
namespace Castle.MicroKernel
{
[Serializable]
public class ComponentReference<T> : IReference<T>
{
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
protected readonly string referencedComponentName;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
protected readonly Type referencedComponentType;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
protected DependencyModel dependencyModel;
protected virtual Type ComponentType => referencedComponentType ?? typeof(T);
public ComponentReference(Type componentType)
{
referencedComponentName = ComponentName.DefaultNameFor(componentType);
referencedComponentType = componentType;
}
public ComponentReference(string referencedComponentName)
{
if (referencedComponentName == null)
throw new ArgumentNullException("referencedComponentName");
this.referencedComponentName = referencedComponentName;
}
public T Resolve(IKernel kernel, CreationContext context)
{
IHandler handler = GetHandler(kernel);
if (handler == null)
throw new DependencyResolverException($"""{referencedComponentName}""");
if (!handler.IsBeingResolvedInContext(context)) {
CreationContext context2 = RebuildContext(handler, context);
try {
return (T)handler.Resolve(context2);
} catch (InvalidCastException innerException) {
throw new ComponentResolutionException($"""{referencedComponentName}""{typeof(T)}""", innerException);
}
}
throw new DependencyResolverException($"""{handler.ComponentModel.Name}""");
}
private IHandler GetHandler(IKernel kernel)
{
return kernel.GetHandler(referencedComponentName);
}
private CreationContext RebuildContext(IHandler handler, CreationContext current)
{
Type type = ComponentType ?? Enumerable.First<Type>(handler.ComponentModel.Services);
if (type.ContainsGenericParameters)
return current;
return new CreationContext(type, current, false);
}
void IReference<T>.Attach(ComponentModel component)
{
dependencyModel = new ComponentDependencyModel(referencedComponentName, ComponentType);
component.Dependencies.Add(dependencyModel);
}
void IReference<T>.Detach(ComponentModel component)
{
if (dependencyModel != null)
component.Dependencies.Remove(dependencyModel);
}
}
}