DefaultComponentInstaller
Default IComponentsInstaller implementation.
using Castle.Core;
using Castle.Core.Configuration;
using Castle.Core.Internal;
using Castle.Core.Resource;
using Castle.MicroKernel;
using Castle.MicroKernel.Registration;
using Castle.MicroKernel.SubSystems.Configuration;
using Castle.MicroKernel.SubSystems.Conversion;
using Castle.Windsor.Configuration.Interpreters;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Reflection;
namespace Castle.Windsor.Installer
{
public class DefaultComponentInstaller : IComponentsInstaller
{
private string assemblyName;
public void SetUp(IWindsorContainer container, IConfigurationStore store)
{
IConversionManager converter = container.Kernel.GetSubSystem(SubSystemConstants.ConversionManagerKey) as IConversionManager;
SetUpInstallers(store.GetInstallers(), container, converter);
SetUpFacilities(store.GetFacilities(), container, converter);
SetUpComponents(store.GetComponents(), container, converter);
SetUpChildContainers(store.GetConfigurationForChildContainers(), container);
}
protected virtual void SetUpInstallers(IConfiguration[] installers, IWindsorContainer container, IConversionManager converter)
{
Dictionary<Type, IWindsorInstaller> dictionary = new Dictionary<Type, IWindsorInstaller>();
HashSet<Assembly> assemblies = new HashSet<Assembly>();
foreach (IConfiguration installer in installers) {
AddInstaller(installer, dictionary, converter, assemblies);
}
if (dictionary.Count != 0)
container.Install(dictionary.Values.ToArray());
}
private void AddInstaller(IConfiguration installer, Dictionary<Type, IWindsorInstaller> cache, IConversionManager conversionManager, ICollection<Assembly> assemblies)
{
string value = ((NameValueCollection)installer.get_Attributes())["type"];
if (!string.IsNullOrEmpty(value)) {
Type type = conversionManager.PerformConversion<Type>(value);
AddInstaller(cache, type);
} else {
assemblyName = ((NameValueCollection)installer.get_Attributes())["assembly"];
if (!string.IsNullOrEmpty(assemblyName)) {
Assembly assemblyNamed = ReflectionUtil.GetAssemblyNamed(assemblyName);
if (!assemblies.Contains(assemblyNamed)) {
assemblies.Add(assemblyNamed);
GetAssemblyInstallers(cache, assemblyNamed);
}
} else {
string directoryName = ((NameValueCollection)installer.get_Attributes())["directory"];
string mask = ((NameValueCollection)installer.get_Attributes())["fileMask"];
string text = ((NameValueCollection)installer.get_Attributes())["publicKeyToken"];
AssemblyFilter assemblyFilter = new AssemblyFilter(directoryName, mask);
if (text != null)
assemblyFilter.WithKeyToken(text);
foreach (Assembly assembly in ReflectionUtil.GetAssemblies(assemblyFilter)) {
if (!assemblies.Contains(assembly)) {
assemblies.Add(assembly);
GetAssemblyInstallers(cache, assembly);
}
}
}
}
}
private void GetAssemblyInstallers(Dictionary<Type, IWindsorInstaller> cache, Assembly assembly)
{
Type[] exportedTypes = assembly.GetExportedTypes();
foreach (Type item in InstallerTypes(exportedTypes)) {
AddInstaller(cache, item);
}
}
private IEnumerable<Type> InstallerTypes(IEnumerable<Type> types)
{
return types.Where(IsInstaller);
}
private bool IsInstaller(Type type)
{
if (type.IsClass && !type.IsAbstract && !type.IsGenericTypeDefinition)
return type.Is<IWindsorInstaller>();
return false;
}
private void AddInstaller(Dictionary<Type, IWindsorInstaller> cache, Type type)
{
if (!cache.ContainsKey(type)) {
IWindsorInstaller value = type.CreateInstance<IWindsorInstaller>(new object[0]);
cache.Add(type, value);
}
}
protected virtual void SetUpFacilities(IConfiguration[] configurations, IWindsorContainer container, IConversionManager converter)
{
foreach (IConfiguration val in configurations) {
Type subtypeofTBase = converter.PerformConversion<Type>(((NameValueCollection)val.get_Attributes())["type"]);
IFacility facility = subtypeofTBase.CreateInstance<IFacility>(new object[0]);
container.AddFacility(facility);
}
}
private void AssertImplementsService(IConfiguration id, Type service, Type implementation)
{
if (!(service == (Type)null)) {
if (service.IsGenericTypeDefinition)
implementation = implementation.MakeGenericType(service.GetGenericArguments());
if (!service.IsAssignableFrom(implementation)) {
string message = string.Format("Could not set up component '{0}'. Type '{1}' does not implement service '{2}'", ((NameValueCollection)id.get_Attributes())["id"], implementation.AssemblyQualifiedName, service.AssemblyQualifiedName);
throw new ComponentRegistrationException(message);
}
}
}
protected virtual void SetUpComponents(IConfiguration[] configurations, IWindsorContainer container, IConversionManager converter)
{
foreach (IConfiguration val in configurations) {
Type type = GetType(converter, ((NameValueCollection)val.get_Attributes())["type"]);
Type type2 = GetType(converter, ((NameValueCollection)val.get_Attributes())["service"]);
HashSet<Type> services = new HashSet<Type>();
if (type2 != (Type)null)
services.Add(type2);
CollectAdditionalServices(val, converter, services);
string name = null;
if (type != (Type)null) {
AssertImplementsService(val, type2, type);
CastleComponentAttribute defaultsFor = CastleComponentAttribute.GetDefaultsFor(type);
if (defaultsFor.ServicesSpecifiedExplicitly && services.Count == 0)
CollectionExtensions.ForEach<Type>((IEnumerable<Type>)defaultsFor.Services, (Action<Type>)delegate(Type s) {
services.Add(s);
});
name = GetName(defaultsFor, val);
}
if (services.Count != 0 || !(type == (Type)null))
container.Register(Component.For(services).ImplementedBy(type).Named(name));
}
}
private static string GetName(CastleComponentAttribute defaults, IConfiguration component)
{
if (((NameValueCollection)component.get_Attributes())["id-automatic"] != bool.TrueString)
return ((NameValueCollection)component.get_Attributes())["id"];
return defaults.Name;
}
private Type GetType(IConversionManager converter, string typeName)
{
if (typeName == null)
return null;
return converter.PerformConversion<Type>(typeName);
}
private void CollectAdditionalServices(IConfiguration component, IConversionManager converter, ICollection<Type> services)
{
IConfiguration val = component.get_Children().get_Item("forwardedTypes");
if (val != null) {
foreach (IConfiguration item in (List<IConfiguration>)val.get_Children()) {
string value = ((NameValueCollection)item.get_Attributes())["service"];
try {
services.Add(converter.PerformConversion<Type>(value));
} catch (ConverterException innerException) {
throw new ComponentRegistrationException(string.Format("Component {0} defines invalid forwarded type.", ((NameValueCollection)component.get_Attributes())["id"]), innerException);
}
}
}
}
private static void SetUpChildContainers(IConfiguration[] configurations, IWindsorContainer parentContainer)
{
foreach (IConfiguration val in configurations) {
string name = ((NameValueCollection)val.get_Attributes())["name"];
new WindsorContainer(name, parentContainer, new XmlInterpreter(new StaticContentResource(val.get_Value())));
}
}
}
}