ServiceDescriptor
Describes how to select a types service.
using Castle.DynamicProxy.Internal;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Castle.MicroKernel.Registration
{
public class ServiceDescriptor
{
public delegate IEnumerable<Type> ServiceSelector (Type type, Type[] baseTypes);
private readonly BasedOnDescriptor basedOnDescriptor;
private ServiceSelector serviceSelector;
internal ServiceDescriptor(BasedOnDescriptor basedOnDescriptor)
{
this.basedOnDescriptor = basedOnDescriptor;
}
public BasedOnDescriptor AllInterfaces()
{
return Select((Type t, Type[] b) => TypeUtil.GetAllInterfaces(t));
}
public BasedOnDescriptor Base()
{
return Select((Type t, Type[] b) => b);
}
public BasedOnDescriptor DefaultInterfaces()
{
return Select(delegate(Type type, Type[] base) {
ServiceDescriptor serviceDescriptor = this;
return from i in TypeUtil.GetAllInterfaces(type)
where type.Name.Contains(serviceDescriptor.GetInterfaceName(i))
select i;
});
}
public BasedOnDescriptor FirstInterface()
{
return Select(delegate(Type type, Type[] base) {
Type type2 = type.GetInterfaces().FirstOrDefault();
if (type2 == (Type)null)
return null;
return new Type[1] {
type2
};
});
}
public BasedOnDescriptor FromInterface(Type implements)
{
return Select(delegate(Type type, Type[] baseTypes) {
HashSet<Type> hashSet = new HashSet<Type>();
if (implements != (Type)null)
AddFromInterface(type, implements, hashSet);
else {
foreach (Type implements2 in baseTypes) {
AddFromInterface(type, implements2, hashSet);
}
}
if (hashSet.Count == 0) {
foreach (Type item in from t in baseTypes
where t != typeof(object)
select t) {
if (item.IsAssignableFrom(type)) {
hashSet.Add(item);
return hashSet;
}
}
return hashSet;
}
return hashSet;
});
}
public BasedOnDescriptor FromInterface()
{
return FromInterface(null);
}
public BasedOnDescriptor Select(ServiceSelector selector)
{
serviceSelector = (ServiceSelector)Delegate.Combine(serviceSelector, selector);
return basedOnDescriptor;
}
public BasedOnDescriptor Select(IEnumerable<Type> types)
{
return Select((Type param0, Type[] param1) => types);
}
public BasedOnDescriptor Self()
{
return Select((Type t, Type[] b) => new Type[1] {
t
});
}
internal ICollection<Type> GetServices(Type type, Type[] baseType)
{
HashSet<Type> hashSet = new HashSet<Type>();
if (this.serviceSelector != null) {
Delegate[] invocationList = this.serviceSelector.GetInvocationList();
for (int i = 0; i < invocationList.Length; i++) {
ServiceSelector serviceSelector = (ServiceSelector)invocationList[i];
IEnumerable<Type> enumerable = serviceSelector(type, baseType);
if (enumerable != null) {
foreach (Type item in enumerable.Select(WorkaroundCLRBug)) {
hashSet.Add(item);
}
}
}
}
return hashSet;
}
private void AddFromInterface(Type type, Type implements, ICollection<Type> matches)
{
foreach (Type topLevelInterface in GetTopLevelInterfaces(type)) {
if (topLevelInterface.GetInterface(implements.FullName, false) != (Type)null)
matches.Add(topLevelInterface);
}
}
private string GetInterfaceName(Type interface)
{
string name = interface.Name;
if (name.Length > 1 && name[0] == 'I' && char.IsUpper(name[1]))
return name.Substring(1);
return name;
}
private IEnumerable<Type> GetTopLevelInterfaces(Type type)
{
Type[] interfaces = type.GetInterfaces();
List<Type> list = new List<Type>(interfaces);
Type[] array = interfaces;
foreach (Type type2 in array) {
Type[] interfaces2 = type2.GetInterfaces();
foreach (Type item in interfaces2) {
list.Remove(item);
}
}
return list;
}
private static Type WorkaroundCLRBug(Type serviceType)
{
if (!serviceType.IsInterface)
return serviceType;
if (serviceType.IsGenericType && serviceType.ReflectedType == (Type)null) {
bool flag = false;
Type[] genericArguments = serviceType.GetGenericArguments();
foreach (Type type in genericArguments) {
flag |= type.IsGenericParameter;
}
if (flag)
return serviceType.GetGenericTypeDefinition();
}
return serviceType;
}
}
}